ies1000_sm.c 44 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829
  1. #include "plt.h"
  2. static struct state_t ies1000_states[] = {
  3. { SMST_LAUNCH, "launch" },
  4. { SMST_STDBY, "stdby" },
  5. { SMST_STOP, "stop" },
  6. { SMST_READY, "ready" },
  7. { SMST_DHG, "dhg" },
  8. { SMST_CHG, "chg" },
  9. { SMST_OFFGRID, "offgrid" },
  10. { SMST_ERR, "err" },
  11. };
  12. static struct err_t ies1000_errs[] = {
  13. {IES1000ERR_NONE, "none"},
  14. // launch IES1000ERR_LAUNCH_COMMERR
  15. {IES1000ERR_LAUNCH_COMMERR, "launch, comm err"},
  16. // err
  17. {IES1000ERR_ERR_COMMERR, "err, comm err"},
  18. {IES1000ERR_ERR_PWRUP, "err, pwrup"},
  19. // stdby
  20. {IES1000ERR_STDBY_COMMERR, "stdby, comm err"},
  21. {IES1000ERR_STDBY_CHK_DEVAPS0_FAIL_AFTER_SET, "stdby, chk aps = 0 fail"},
  22. {IES1000ERR_STDBY_CHK_STOP_FAIL_AFTER_SET, "stdby, chk stop fail"},
  23. {IES1000ERR_STDBY_WAIT_STOP_TIMEOUT, "stdby, wait stop timeout"},
  24. {IES1000ERR_STDBY_WAIT_RUN_TIMEOUT, "stdby, wait run state timeout"},
  25. {IES1000ERR_STDBY_UNKOWN_RUNSTAT, "stdby, unknown run state"},
  26. // stop
  27. {IES1000ERR_STOP_COMMERR, "stop, comm err"},
  28. {IES1000ERR_STOP_NONE_STOP_DETECTED, "stop, none stop run state detected"},
  29. {IES1000ERR_STOP_CHK_DEVAPS0_FAIL_AFTER_SET, "stop, chk dev aps = 0 fail"},
  30. {IES1000ERR_STOP_WAIT_IDLE_TIMEOUT, "stop, wait idle timeout"},
  31. {IES1000ERR_STOP_WAIT_RUNMOD_OFFGRID_TIMEOUT, "stop, wait run mod = offgrid timeout"},
  32. // ready
  33. {IES1000ERR_READY_COMMERR, "ready, comm err"},
  34. {IES1000ERR_READY_WAIT_STOP_TIMEOUT, "ready, wait stop timeout"},
  35. {IES1000ERR_READY_WAIT_RUN4DHG_TIMEOUT, "ready, wait run state for dhg timeout"},
  36. {IES1000ERR_READY_WAIT_AP4DHG_TIMEOUT, "ready, wait ap for dhg timeout"},
  37. {IES1000ERR_READY_WAIT_RUN4CHG_TIMEOUT, "ready, wait run state for chg timeout"},
  38. {IES1000ERR_READY_WAIT_AP4CHG_TIMEOUT, "ready, wait ap for chg tiemout"},
  39. {IES1000ERR_READY_NONIDLE_DETECTED, "ready, non idle state detected"},
  40. {IES1000ERR_READY_SET_DEVAPS_FAIL, "ready, set dev aps fail"},
  41. {IES1000ERR_READY_SEND_STARTCMD_FAIL, "ready, send startcmd fail"},
  42. {IES1000ERR_READY_WAIT_RUNMOD_OFFGRID_FOR_OFFGRID_TIMEOUT, "ready, wait run mode = offgrid for offgrid timeout"},
  43. {IES1000ERR_READY_WAIT_IDLE_FOR_OFFGRID_TIMEOUT, "ready, wait idle for offgrid timeout"},
  44. {IES1000ERR_READY_WAIT_TARGET_VOLTAGE_FOR_OFFGRID_TIMEOUT, "stop, wait target voltage for offgrid timeout"},
  45. {IES1000ERR_READY_WAIT_RUNMOD_ONGRID_FOR_DHG_TIMEOUT, "ready, wait runmod = ongrid for dhg timeout"},
  46. {IES1000ERR_READY_WAIT_RUNMOD_ONGRID_FOR_CHG_TIMEOUT, "ready, wait runmod = ongrid for chg timeout"},
  47. // dhg
  48. {IES1000ERR_DHG_COMMERR, "dhg, comm err"},
  49. {IES1000ERR_DHG_WAIT_DEVAPS0_TIMEOUT, "dhg, wait dev aps = 0 timeout"},
  50. {IES1000ERR_DHG_WAIT_AP0_TIMEOUT, "dhg, wait ap = 0 timeout"},
  51. {IES1000ERR_DHG_NONDHG_DETECTED, "dhg, non-dhg detected"},
  52. {IES1000ERR_DHG_WAIT_DEVAPS0_FOR_READYCMD_TIMEOUT, "dhg, wait devaps=0 for readycmd timeout"},
  53. {IES1000ERR_DHG_WAIT_AP0_FOR_READYCMD_TIMEOUT, "dhg, wait ap=0 for readycmd timeout"},
  54. {IES1000ERR_DHG_WAIT_RUNSTATE_IDLE_FOR_READYCMD_TIMEOUT, "dhg, wait run state=idle for readycmd timeout"},
  55. // chg
  56. {IES1000ERR_CHG_COMMERR, "chg, comm err"},
  57. {IES1000ERR_CHG_WAIT_DEVAPS0_TIMEOUT, "chg, wait dev aps = 0 timeout"},
  58. {IES1000ERR_CHG_WAIT_AP0_TIMEOUT, "chg, wait ap = 0 timeout"},
  59. {IES1000ERR_CHG_NONCHG_DETECTED, "chg, non-chg detected"},
  60. {IES1000ERR_CHG_WAIT_DEVAPS0_FOR_READYCMD_TIMEOUT, "chg, wait devaps=0 for readycmd timeout"},
  61. {IES1000ERR_CHG_WAIT_AP0_FOR_READYCMD_TIMEOUT, "chg, wait ap=0 for readycmd timeout"},
  62. {IES1000ERR_CHG_WAIT_RUNSTATE_IDLE_FOR_READYCMD_TIMEOUT, "chg, wait run state=idle for readycmd timeout"},
  63. // offgrid
  64. {IES1000ERR_OFFGRID_ERRSTAT_DETECTED, "offgrid, err state detected"},
  65. {IES1000ERR_OFFGRID_NON_DHGCHG_DETECTED, "offgrid, non dhg chg state detected"},
  66. };
  67. int ies1000_sm_init(int idx)
  68. {
  69. struct statemachine_t* sm = &ies1000[idx].sm;
  70. sm_reset_timing(sm, 10, 10);
  71. sm->states = ies1000_states;
  72. sm->state_nbr = sizeof(ies1000_states)/sizeof(struct state_t);
  73. sm->errs = ies1000_errs;
  74. sm->err_nbr = sizeof(ies1000_errs)/sizeof(struct err_t);
  75. sm_set_state( sm, SMST_LAUNCH, IES1000ERR_NONE );
  76. return 0;
  77. }
  78. static void ies1000_sm_launch( int idx )
  79. {
  80. struct ies1000_t* dev = &ies1000[idx];
  81. struct comm_t* comm = &dev->comm;
  82. struct statemachine_t* sm = &dev->sm;
  83. if( sm_get_step(sm) == 0 ){ // entry
  84. log_dbg("%s, idx:%d, state:%s, step:%d, entry", __func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  85. ies1000_reset_cmd(idx);
  86. ies1000_comm_reset(idx);
  87. sm_set_step(sm, 20);
  88. }
  89. /*if( sm_get_step(sm) == 0 ){ // entry
  90. log_dbg("%s, idx:%d, state:%s, step:%d, entry", __func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  91. ies1000_reset_cmd(idx);
  92. sm_set_step(sm, 10);
  93. }else if( sm_get_step(sm) == 10 ){ // wait cmd
  94. if( ies1000_get_cmd(idx) == CMD_SM_STDBY){ // stdby cmd
  95. log_dbg("%s, idx:%d, state:%s, step:%d, get stdby cmd, reset comm then chk",
  96. __func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  97. ies1000_reset_cmd(idx);
  98. ies1000_comm_reset(idx);
  99. sm_set_step(sm, 20);
  100. }
  101. }*/else if( sm_get_step(sm) == 20 ){
  102. if( comm_get_state(comm) == COMMST_NORMAL){
  103. log_dbg("%s, idx:%d, state:%s, step:%d, comm ok, goto stdby",
  104. __func__, idx,sm_get_szstate(sm), sm_get_step(sm));
  105. sm_set_state(sm, SMST_STDBY, IES1000ERR_NONE);
  106. }else{
  107. log_dbg("%s, idx:%d, state:%s, step:%d, comm err detected, goto err",
  108. __func__, idx,sm_get_szstate(sm), sm_get_step(sm));
  109. sm_set_state(sm, SMST_ERR, IES1000ERR_LAUNCH_COMMERR);
  110. }
  111. }
  112. }
  113. static void ies1000_sm_err( int idx )
  114. {
  115. struct ies1000_t* dev = &ies1000[idx];
  116. struct comm_t* comm = &ies1000[idx].comm;
  117. struct statemachine_t* sm = &ies1000[idx].sm;
  118. static double ts_last_try;
  119. double ts;
  120. if( sm_get_step(sm) == 0 ){ // entry
  121. log_dbg("%s, idx:%d, state:%s, step:%d, entry", __func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  122. ies1000_reset_cmd(idx);
  123. sm_set_step(sm, 10);
  124. ts_last_try = sm_get_timeofday();
  125. }else if( sm_get_step(sm) == 10 ){ // wait cmd
  126. ts = sm_get_timeofday();
  127. if( ies1000_get_cmd(idx) == CMD_SM_STDBY){ // stdby cmd
  128. log_dbg("%s, idx:%d, state:%s, step:%d, get stdby cmd, reset comm then chk",
  129. __func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  130. ies1000_reset_cmd(idx);
  131. ies1000_comm_reset(idx);
  132. sm_set_step(sm, 20);
  133. }else if( comm_get_state(comm) != COMMST_NORMAL && (ts - ts_last_try > 60000) ){ // 60s
  134. log_dbg("%s, idx:%d, state:%s, step:%d,comm:%s,reset comm",
  135. __func__, idx, sm_get_szstate(sm), sm_get_step(sm),comm_get_state_str(comm));
  136. ts_last_try = ts;
  137. ies1000_comm_reset(idx);
  138. }
  139. }else if( sm_get_step(sm) == 20 ){ /* chk comm state */
  140. if( comm_get_state(comm) == COMMST_NORMAL){
  141. log_dbg("%s, idx:%d, state:%s, step:%d, comm ok, goto stdby",
  142. __func__, idx,sm_get_szstate(sm), sm_get_step(sm));
  143. sm_set_state(sm, SMST_STDBY, IES1000ERR_NONE);
  144. }else{
  145. log_dbg("%s, idx:%d, state:%s, step:%d, comm err detected, stay err",
  146. __func__, idx,sm_get_szstate(sm), sm_get_step(sm));
  147. sm_set_state(sm, SMST_ERR, IES1000ERR_ERR_COMMERR);
  148. }
  149. }
  150. }
  151. static void ies1000_sm_stdby( int idx )
  152. {
  153. struct ies1000_t* dev = &ies1000[idx];
  154. struct comm_t* comm = &ies1000[idx].comm;
  155. struct statemachine_t* sm = &ies1000[idx].sm;
  156. /* chk comm state */
  157. if( comm_get_state(comm) != COMMST_NORMAL){
  158. log_dbg("%s, idx:%d, state:%s, step:%d, comm err detected, goto err",
  159. __func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  160. sm_set_state(sm, SMST_ERR, IES1000ERR_STDBY_COMMERR);
  161. return;
  162. }
  163. if( sm_get_step(sm) == 0 ){ /* entry */
  164. ies1000_reset_cmd(idx);
  165. sm_set_step(sm, 10);
  166. }else if( sm_get_step(sm) == 10 ){ /* wait cmd */
  167. if( ies1000_get_cmd(idx) == CMD_SM_STOP ){ /* stop cmd */
  168. log_dbg("%s, idx:%d, state:%s, step:%d, get stop cmd, chk devaps = 0 ?",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  169. ies1000_reset_cmd(idx);
  170. sm_set_step(sm, 20);
  171. }
  172. }else if( sm_get_step(sm) == 20 ){ /* chk devaps = 0 ? */
  173. if( ies1000_get_dev_aps(idx) != 0 ){
  174. log_dbg("%s, idx:%d, state:%s, step:%d, devaps != 0 detected, set it to 0, wait and chk",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  175. ies1000_set_dev_aps(idx, 0);
  176. sm_set_step(sm, 30);
  177. }else{
  178. log_dbg("%s, idx:%d, state:%s, step:%d, devaps = 0 detected, chk stop state",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  179. sm_set_step(sm, 40);
  180. }
  181. }else if( sm_get_step(sm) == 30 ){ /* wait and chk devaps = 0 */
  182. if( ies1000_get_dev_aps(idx) == 0 ){
  183. log_dbg("%s, idx:%d, state:%s, step:%d, devaps = 0 detected, chk stop state",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  184. sm_set_step(sm, 40);
  185. }else{
  186. log_dbg("%s, idx:%d, state:%s, step:%d, chk devaps = 0 fail after set, goto err",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  187. sm_set_state(sm, SMST_ERR, IES1000ERR_STDBY_CHK_DEVAPS0_FAIL_AFTER_SET);
  188. }
  189. }else if( sm_get_step(sm) == 40 ){ /* chk runstate = stop ? */
  190. if( IES1000_RUNSTAT_STOP != ies1000_get_runstat(idx) ){
  191. log_dbg("%s, idx:%d, state:%s, step:%d, non-stop run state detected, send stop cmd, wait and chk",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  192. ies1000_set_dev_stopcmd(idx);
  193. sm_set_step(sm, 50);
  194. sm_set_count(sm, 0);
  195. }else{
  196. log_dbg("%s, idx:%d, state:%s, step:%d, stop run state detected, goto stop",
  197. __func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  198. sm_set_state(sm, SMST_STOP, IES1000ERR_NONE);
  199. }
  200. }else if( sm_get_step(sm) == 50 ){ /* wait run state = stop after stopcmd*/
  201. if( IES1000_RUNSTAT_STOP == ies1000_get_runstat(idx) ){
  202. log_dbg("%s, idx:%d, state:%s, step:%d, stop run state detected, goto stop",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  203. sm_set_state(sm, SMST_STOP, IES1000ERR_NONE);
  204. }else{
  205. sm_inc_count(sm);
  206. if( sm_get_count(sm) >= 100){
  207. log_dbg("%s, idx:%d, state:%s, step:%d, wait stop run state timeout, goto err",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  208. sm_set_state(sm, SMST_ERR, IES1000ERR_STDBY_WAIT_STOP_TIMEOUT);
  209. }else{
  210. log_dbg("%s, idx:%d, state:%s, step:%d, waiting stop run state, count:%d",__func__, idx, sm_get_szstate(sm), sm_get_step(sm), sm_get_count(sm));
  211. }
  212. }
  213. }
  214. }
  215. static void ies1000_sm_offgrid( int idx )
  216. {
  217. struct ies1000_t* dev = &ies1000[idx];
  218. struct comm_t* comm = &ies1000[idx].comm;
  219. struct statemachine_t* sm = &ies1000[idx].sm;
  220. // chk comm state
  221. if( comm_get_state(comm) != COMMST_NORMAL){
  222. log_dbg("%s, idx:%d, state:%s, step:%d, comm err detected, goto err",
  223. __func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  224. sm_set_state(sm, SMST_ERR, IES1000ERR_STOP_COMMERR);
  225. return;
  226. }
  227. if( sm_get_step(sm) == 0 ){ // entry
  228. ies1000_reset_cmd(idx);
  229. sm_set_step(sm, 10);
  230. }else if( sm_get_step(sm) == 10 ){ // wait cmd and chk
  231. if( ies1000_get_cmd(idx) == CMD_SM_READY ){ // ready cmd
  232. log_dbg("%s, idx:%d, state:%s, step:%d, get ready cmd, set dev idlecmd, goto ready",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  233. ies1000_reset_cmd(idx);
  234. ies1000_set_dev_idlecmd(idx);
  235. sm_set_state(sm, SMST_READY, IES1000ERR_NONE);
  236. }else if( ies1000_get_errstat(idx) != 0){
  237. log_dbg("%s, idx:%d, state:%s, step:%d, err state detected, goto err",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  238. sm_set_state(sm, SMST_ERR, IES1000ERR_OFFGRID_ERRSTAT_DETECTED);
  239. }else if( ies1000_get_runstat(idx) != IES1000_RUNSTAT_CHG && ies1000_get_runstat(idx) != IES1000_RUNSTAT_DHG){
  240. log_dbg("%s, idx:%d, state:%s, step:%d, non dhg chg run state detected, goto err",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  241. sm_set_state(sm, SMST_ERR, IES1000ERR_OFFGRID_NON_DHGCHG_DETECTED);
  242. }else{
  243. }
  244. }
  245. }
  246. static void ies1000_sm_stop( int idx )
  247. {
  248. struct ies1000_t* dev = &ies1000[idx];
  249. struct comm_t* comm = &ies1000[idx].comm;
  250. struct statemachine_t* sm = &ies1000[idx].sm;
  251. /* chk comm state */
  252. if( comm_get_state(comm) != COMMST_NORMAL){
  253. log_dbg("%s, idx:%d, state:%s, step:%d, comm err detected, goto err",
  254. __func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  255. sm_set_state(sm, SMST_ERR, IES1000ERR_STOP_COMMERR);
  256. return;
  257. }
  258. if( sm_get_step(sm) == 0 ){ // entry
  259. ies1000_reset_cmd(idx);
  260. ies1000_set_aps(idx, 0);
  261. sm_set_step(sm, 10);
  262. }else if( sm_get_step(sm) == 10 ){ // wait cmd and chk
  263. if( ies1000_get_cmd(idx) == CMD_SM_STDBY ){ // stdby cmd
  264. log_dbg("%s, idx:%d, state:%s, step:%d, get stdby cmd, goto stdby",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  265. ies1000_reset_cmd(idx);
  266. sm_set_state(sm, SMST_STDBY, IES1000ERR_NONE);
  267. }else if( ies1000_get_cmd(idx) == CMD_SM_READY ){ // ready cmd
  268. log_dbg("%s, idx:%d, state:%s, step:%d, get ready cmd, set dev resetcmd, chk dev aps",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  269. ies1000_reset_cmd(idx);
  270. sm_set_step(sm, 20);
  271. ies1000_set_dev_resetcmd(idx);
  272. }else{ /* no cmd, do chking */
  273. if( IES1000_RUNSTAT_STOP != ies1000_get_runstat(idx) ){
  274. log_dbg("%s, idx:%d, state:%s, step:%d, run state != stop detected, goto err",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  275. sm_set_state(sm, SMST_ERR, IES1000ERR_STOP_NONE_STOP_DETECTED);
  276. }
  277. }
  278. }else if( sm_get_step(sm) == 20 ){ /* chk devaps = 0 ? */
  279. if( ies1000_get_dev_aps(idx) != 0 ){
  280. log_dbg("%s, idx:%d, state:%s, step:%d, dev aps != 0 detected, set it to 0, then chk",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  281. ies1000_set_dev_aps(idx, 0);
  282. sm_set_step(sm, 30);
  283. }else{
  284. log_dbg("%s, idx:%d, state:%s, step:%d, dev aps = 0 detected, set dev runmod = offgrid, wait and chk",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  285. ies1000_set_dev_runmod(idx, IES1000_RUNMOD_OFFGRID);
  286. sm_set_step(sm, 40);
  287. }
  288. }else if( sm_get_step(sm) == 30 ){ /* wait and chk devaps = 0 */
  289. if( ies1000_get_dev_aps(idx) == 0 ){
  290. log_dbg("%s, idx:%d, state:%s, step:%d, dev aps = 0 detected",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  291. sm_set_step(sm, 40);
  292. }else{
  293. log_dbg("%s, idx:%d, state:%s, step:%d, chk dev aps = 0 fail, goto err",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  294. sm_set_state(sm, SMST_ERR, IES1000ERR_STOP_CHK_DEVAPS0_FAIL_AFTER_SET);
  295. }
  296. }else if( sm_get_step(sm) == 40 ){ // wait pcs runmod = offgrid
  297. if( IES1000_RUNMOD_OFFGRID == ies1000_get_runmod(idx) ){
  298. log_dbg("%s, idx:%d, state:%s, step:%d, chk pcs runmod = offgrid ok, set dev idle, wait and chk",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  299. ies1000_set_dev_idlecmd(idx);
  300. sm_set_step(sm, 41);
  301. sm_set_count(sm, 0);
  302. }else{
  303. sm_inc_count(sm);
  304. if( sm_get_count(sm) >= 50 ){ //2.5s
  305. sm_set_state(sm, SMST_ERR, IES1000ERR_STOP_WAIT_RUNMOD_OFFGRID_TIMEOUT);
  306. log_dbg("%s, idx:%d, state:%s, step:%d, wait run mode = offgrid timeout, goto err",
  307. __func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  308. }else{
  309. log_dbg("%s, idx:%d, state:%s, step:%d, waiting run mode = offgrid, count:%d",
  310. __func__, idx, sm_get_szstate(sm), sm_get_step(sm), sm_get_count(sm));
  311. }
  312. }
  313. }else if( sm_get_step(sm) == 41 ){ // wait pcs idle
  314. if( IES1000_RUNSTAT_IDLE == ies1000_get_runstat(idx) ){
  315. log_dbg("%s, idx:%d, state:%s, step:%d, chk pcs idle ok, goto ready",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  316. sm_set_state(sm, SMST_READY, IES1000ERR_NONE);
  317. }else{
  318. sm_inc_count(sm);
  319. if( sm_get_count(sm) >= 100 ){ /* 5s */
  320. sm_set_state(sm, SMST_ERR, IES1000ERR_STOP_WAIT_IDLE_TIMEOUT);
  321. log_dbg("%s, idx:%d, state:%s, step:%d, wait idle run state timeout, goto err",
  322. __func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  323. }else{
  324. log_dbg("%s, idx:%d, state:%s, step:%d, waiting idle run state, count:%d",
  325. __func__, idx, sm_get_szstate(sm), sm_get_step(sm), sm_get_count(sm));
  326. }
  327. }
  328. }
  329. }
  330. static void ies1000_sm_ready( int idx )
  331. {
  332. struct ies1000_t* dev = &ies1000[idx];
  333. struct comm_t* comm = &ies1000[idx].comm;
  334. struct statemachine_t* sm = &ies1000[idx].sm;
  335. int aps = ies1000_get_aps(idx);
  336. int ap = ies1000_get_ap(idx);
  337. /* chk comm state */
  338. if( comm_get_state(comm) != COMMST_NORMAL){
  339. log_dbg("%s, idx:%d, state:%s, step:%d, comm err detected, goto err",
  340. __func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  341. sm_set_state(sm, SMST_ERR, IES1000ERR_READY_COMMERR);
  342. return;
  343. }
  344. if( sm_get_step(sm) == 0 ){ // entry
  345. log_dbg("%s, idx:%d, state:%s, step:%d, entry",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  346. ies1000_reset_cmd(idx);
  347. ies1000_reset_aps(idx);
  348. sm_set_step(sm, 10);
  349. }else if( sm_get_step(sm) == 10 ){ // wait and chk
  350. if( ies1000_get_cmd(idx) == CMD_SM_STOP){ // stop cmd
  351. log_dbg("%s, idx:%d, state:%s, step:%d, get stop cmd, dev stop cmd sent, wait and chk",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  352. ies1000_reset_cmd(idx);
  353. ies1000_set_dev_stopcmd(idx);
  354. sm_set_step(sm, 20);
  355. sm_set_count(sm, 0);
  356. }else if( aps > 0 ){ // new aps, prepare to dhg
  357. log_dbg("%s, idx:%d, state:%s, step:%d, aps > 0 detected, %d, set dev run mode = ongrid, wait and chk",
  358. __func__, idx, sm_get_szstate(sm), sm_get_step(sm), aps);
  359. ies1000_set_dev_runmod(idx, IES1000_RUNMOD_ONGRID);
  360. sm_set_step(sm, 30);
  361. sm_set_count(sm, 0);
  362. }else if( aps < 0 ){ // new aps, prepare to chg
  363. log_dbg("%s, idx:%d, state:%s, step:%d, aps < 0 detected, %d, set dev run mode = ongrid, wait and chk",
  364. __func__, idx, sm_get_szstate(sm), sm_get_step(sm), aps);
  365. ies1000_set_dev_runmod(idx, IES1000_RUNMOD_ONGRID);
  366. sm_set_step(sm, 40);
  367. sm_set_count(sm, 0);
  368. }else if( ies1000_get_cmd(idx) == CMD_SM_OFFGRID ){ // offgrid cmd
  369. log_dbg("%s, idx:%d, state:%s, step:%d, get offgrid cmd, set dev run mode = offgrid, wait and chk",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  370. ies1000_reset_cmd(idx);
  371. ies1000_set_dev_runmod(idx, IES1000_RUNMOD_OFFGRID);
  372. sm_set_step(sm, 500);
  373. sm_set_count(sm, 0);
  374. }else if( ies1000_get_runstat(idx) != IES1000_RUNSTAT_IDLE){
  375. log_dbg("%s, idx:%d, state:%s, step:%d, run state != idle detected, %d, goto err",
  376. __func__, idx, sm_get_szstate(sm), sm_get_step(sm), ies1000_get_runstat(idx));
  377. sm_set_state(sm, SMST_ERR, IES1000ERR_READY_NONIDLE_DETECTED);
  378. }
  379. }else if( sm_get_step(sm) == 20){ /* wait and chk run state = stop */
  380. if( ies1000_get_runstat(idx) == IES1000_RUNSTAT_STOP ){
  381. log_dbg("%s, idx:%d, state:%s, step:%d, dev run state = stop detected, goto stop",
  382. __func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  383. sm_set_state(sm, SMST_STOP, IES1000ERR_NONE);
  384. }else{
  385. sm_inc_count(sm);
  386. if(sm_get_count(sm) >= 100){
  387. log_dbg("%s, idx:%d, state:%s, step:%d, wait dev run state = stop timeout, goto err",
  388. __func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  389. sm_set_state(sm, SMST_ERR, IES1000ERR_READY_WAIT_STOP_TIMEOUT);
  390. }else{
  391. log_dbg("%s, idx:%d, state:%s, step:%d, waiting dev run state = stop, count:%d",
  392. __func__, idx, sm_get_szstate(sm), sm_get_step(sm), sm_get_count(sm));
  393. }
  394. }
  395. }else if( sm_get_step(sm) == 30 ){ // chk run mode = ongrid for dhg
  396. if( ies1000_get_runmod(idx) == IES1000_RUNMOD_ONGRID ){ /* chk ok */
  397. log_dbg("%s, idx:%d, state:%s, step:%d, chk run mode = ongrid ok, set dev aps, wait and chk to dhg",
  398. __func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  399. if( ies1000_set_dev_aps(idx, aps) == 0 ){
  400. log_dbg("%s, idx:%d, state:%s, step:%d, set dev aps ok", __func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  401. if( ies1000_set_dev_startcmd(idx) == 0 ){
  402. log_dbg("%s, idx:%d, state:%s, step:%d, set dev startcmd ok, wait and chk run state = dhg", __func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  403. sm_set_step(sm, 31);
  404. sm_set_count(sm, 0);
  405. }else{
  406. log_dbg("%s, idx:%d, state:%s, step:%d, set dev startcmd fail, stopcmd sent, goto err", __func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  407. ies1000_set_dev_stopcmd(idx);
  408. sm_set_state(sm, SMST_ERR, IES1000ERR_READY_SEND_STARTCMD_FAIL);
  409. }
  410. }else{
  411. log_dbg("%s, idx:%d, state:%s, step:%d, set dev aps fail, stopcmd sent, goto err", __func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  412. ies1000_set_dev_stopcmd(idx);
  413. sm_set_state(sm, SMST_ERR, IES1000ERR_READY_SET_DEVAPS_FAIL);
  414. }
  415. }else{
  416. sm_inc_count(sm);
  417. if( sm_get_count(sm) >= 50 ){
  418. log_dbg("%s, idx:%d, state:%s, step:%d, wait run mode = ongrid for dhg timeout, goto err",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  419. sm_set_state(sm, SMST_ERR, IES1000ERR_READY_WAIT_RUNMOD_ONGRID_FOR_DHG_TIMEOUT);
  420. }else{
  421. log_dbg("%s, idx:%d, state:%s, step:%d, waiting run mode = ongrid for dhg, count:%d",
  422. __func__, idx, sm_get_szstate(sm), sm_get_step(sm), sm_get_count(sm));
  423. }
  424. }
  425. }else if( sm_get_step(sm) == 31 ){ // chk run state = dhg
  426. if( ies1000_get_runstat(idx) == IES1000_RUNSTAT_DHG ){ /* chk ok */
  427. log_dbg("%s, idx:%d, state:%s, step:%d, chk runstate = dhg ok, chk ap",
  428. __func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  429. sm_set_step(sm, 32);
  430. sm_set_count(sm, 0);
  431. }else{
  432. sm_inc_count(sm);
  433. if( sm_get_count(sm) >= 100 ){
  434. log_dbg("%s, idx:%d, state:%s, step:%d, wait run state for dhg timeout, goto err",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  435. sm_set_state(sm, SMST_ERR, IES1000ERR_READY_WAIT_RUN4DHG_TIMEOUT);
  436. }else{
  437. log_dbg("%s, idx:%d, state:%s, step:%d, waiting run state for dhg, count:%d",
  438. __func__, idx, sm_get_szstate(sm), sm_get_step(sm), sm_get_count(sm));
  439. }
  440. }
  441. }else if( sm_get_step(sm) == 32 ){ // chk ap > 0
  442. if( ap > 0 ){ /* chk ok */
  443. log_dbg("%s, idx:%d, state:%s, step:%d, ap > 0 detected, %d, goto dhg",
  444. __func__, idx, sm_get_szstate(sm), sm_get_step(sm), ap);
  445. sm_set_state(sm, SMST_DHG, IES1000ERR_NONE);
  446. }else{
  447. sm_inc_count(sm);
  448. if( sm_get_count(sm) >= 100 ){
  449. sm_set_state(sm, SMST_ERR, IES1000ERR_READY_WAIT_AP4DHG_TIMEOUT);
  450. log_dbg("%s, idx:%d, state:%s, step:%d, wait ap > 0 for dhg timeout, goto err",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  451. }else{
  452. log_dbg("%s, idx:%d, state:%s, step:%d, waiting ap > 0 for dhg, count:%d",
  453. __func__, idx, sm_get_szstate(sm), sm_get_step(sm), sm_get_count(sm));
  454. }
  455. }
  456. }else if( sm_get_step(sm) == 40 ){ // chk run mode = ongrid for chg
  457. if( ies1000_get_runmod(idx) == IES1000_RUNMOD_ONGRID ){ /* chk ok */
  458. log_dbg("%s, idx:%d, state:%s, step:%d, run mode = ongrid detected, set dev aps, wait and chk to chg",
  459. __func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  460. if( ies1000_set_dev_aps(idx, aps) == 0 ){
  461. log_dbg("%s, idx:%d, state:%s, step:%d, set dev aps ok", __func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  462. if( ies1000_set_dev_startcmd(idx) == 0 ){
  463. log_dbg("%s, idx:%d, state:%s, step:%d, set dev startcmd ok, wait and chk run state = chg", __func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  464. sm_set_step(sm, 41);
  465. sm_set_count(sm, 0);
  466. }else{
  467. log_dbg("%s, idx:%d, state:%s, step:%d, set dev startcmd fail, stopcmd sent, goto err", __func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  468. ies1000_set_dev_stopcmd(idx);
  469. sm_set_state(sm, SMST_ERR, IES1000ERR_READY_SEND_STARTCMD_FAIL);
  470. }
  471. }else{
  472. log_dbg("%s, idx:%d, state:%s, step:%d, set dev aps fail, stopcmd sent, goto err", __func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  473. ies1000_set_dev_stopcmd(idx);
  474. sm_set_state(sm, SMST_ERR, IES1000ERR_READY_SET_DEVAPS_FAIL);
  475. }
  476. }else{
  477. sm_inc_count(sm);
  478. if( sm_get_count(sm) >= 50 ){
  479. log_dbg("%s, idx:%d, state:%s, step:%d, wait run mode = ongrid for chg timeout, goto err",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  480. sm_set_state(sm, SMST_ERR, IES1000ERR_READY_WAIT_RUNMOD_ONGRID_FOR_CHG_TIMEOUT);
  481. }else{
  482. log_dbg("%s, idx:%d, state:%s, step:%d, waiting run mode = ongrid for chg, count:%d",
  483. __func__, idx, sm_get_szstate(sm), sm_get_step(sm), sm_get_count(sm));
  484. }
  485. }
  486. }else if( sm_get_step(sm) == 41 ){ // chk run state = chg
  487. if( ies1000_get_runstat(idx) == IES1000_RUNSTAT_CHG ){ // chk ok
  488. log_dbg("%s, idx:%d, state:%s, step:%d, dev run state = chg detected, chk ap",
  489. __func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  490. sm_set_step(sm, 42);
  491. sm_set_count(sm, 0);
  492. }else{
  493. sm_inc_count(sm);
  494. if( sm_get_count(sm) >= 100 ){
  495. log_dbg("%s, idx:%d, state:%s, step:%d, wait run state for chg timeout, goto err",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  496. sm_set_state(sm, SMST_ERR, IES1000ERR_READY_WAIT_RUN4CHG_TIMEOUT);
  497. }else{
  498. log_dbg("%s, idx:%d, state:%s, step:%d, waiting run state for chg, count:%d",
  499. __func__, idx, sm_get_szstate(sm), sm_get_step(sm), sm_get_count(sm));
  500. }
  501. }
  502. }else if( sm_get_step(sm) == 42 ){ // chk ap for chg
  503. if( ap < 0 ){ /* chk ok */
  504. log_dbg("%s, idx:%d, state:%s, step:%d, ap = %d < 0 detected, goto chg",
  505. __func__, idx, sm_get_szstate(sm), sm_get_step(sm), ap);
  506. sm_set_state(sm, SMST_CHG, IES1000ERR_NONE);
  507. }else{
  508. sm_inc_count(sm);
  509. if( sm_get_count(sm) >= 100 ){
  510. sm_set_state(sm, SMST_ERR, IES1000ERR_READY_WAIT_AP4CHG_TIMEOUT);
  511. log_dbg("%s, idx:%d, state:%s, step:%d, wait ap < 0 for chg timeout, goto err",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  512. }else{
  513. log_dbg("%s, idx:%d, state:%s, step:%d, waiting ap < 0 for chg, count:%d",
  514. __func__, idx, sm_get_szstate(sm), sm_get_step(sm), sm_get_count(sm));
  515. }
  516. }
  517. }else if( sm_get_step(sm) == 500 ){ // wait run mode = offgrid for offgrid
  518. if( IES1000_RUNMOD_OFFGRID == ies1000_get_runmod(idx) ){
  519. log_dbg("%s, idx:%d, state:%s, step:%d, chk run mode = offgrid ok, set dev startcmd, wait and chk voltage",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  520. ies1000_set_dev_startcmd(idx);
  521. sm_set_step(sm, 501);
  522. sm_set_count(sm, 0);
  523. }else{
  524. sm_inc_count(sm);
  525. if( sm_get_count(sm) >= 100 ){ // 5s
  526. sm_set_state(sm, SMST_ERR, IES1000ERR_READY_WAIT_RUNMOD_OFFGRID_FOR_OFFGRID_TIMEOUT);
  527. log_dbg("%s, idx:%d, state:%s, step:%d, wait run mode = offgrid timeout, goto err",
  528. __func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  529. }else{
  530. log_dbg("%s, idx:%d, state:%s, step:%d, waiting run mode = offgrid, count:%d",
  531. __func__, idx, sm_get_szstate(sm), sm_get_step(sm), sm_get_count(sm));
  532. }
  533. }
  534. }else if( sm_get_step(sm) == 501 ){ // chk voltage for offgrid
  535. if( ies1000_get_ua(idx) > 340.0 && ies1000_get_ua(idx) < 420.0){
  536. log_dbg("%s, idx:%d, state:%s, step:%d, chk voltage ok, %.1f, goto offgrid",__func__, idx, sm_get_szstate(sm), sm_get_step(sm), ies1000_get_ua(idx));
  537. sm_set_state(sm, SMST_OFFGRID, IES1000ERR_NONE);
  538. }else{
  539. sm_inc_count(sm);
  540. if( sm_get_count(sm) >= 300 ){ // 15s
  541. log_dbg("%s, idx:%d, state:%s, step:%d, wait voltage to 380 for offgrid timeout, goto err",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  542. sm_set_state(sm, SMST_ERR, IES1000ERR_READY_WAIT_TARGET_VOLTAGE_FOR_OFFGRID_TIMEOUT);
  543. }else{
  544. log_dbg("%s, idx:%d, state:%s, step:%d, wait target voltage for offgrid, count:%d",
  545. __func__, idx, sm_get_szstate(sm), sm_get_step(sm), sm_get_count(sm));
  546. }
  547. }
  548. }
  549. }
  550. static void ies1000_sm_dhg( int idx )
  551. {
  552. struct ies1000_t* dev = &ies1000[idx];
  553. struct comm_t* comm = &ies1000[idx].comm;
  554. struct statemachine_t* sm = &ies1000[idx].sm;
  555. int aps = ies1000_get_aps(idx);
  556. int last_aps = ies1000_get_last_aps(idx);
  557. int ap = ies1000_get_ap(idx);
  558. /* chk comm state */
  559. if( comm_get_state(comm) != COMMST_NORMAL){
  560. log_dbg("%s, idx:%d, state:%s, step:%d, comm err detected, goto err",
  561. __func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  562. sm_set_state(sm, SMST_ERR, IES1000ERR_DHG_COMMERR);
  563. return;
  564. }
  565. if( sm_get_step(sm) == 0 ){ // entry
  566. log_dbg("%s, idx:%d, state:%s, step:%d, entry", __func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  567. sm_set_step(sm, 10);
  568. ies1000_reset_bsytikchk(idx);
  569. }else if( sm_get_step(sm) == 10 ){ // wait and chk
  570. if( ies1000_get_cmd(idx) == CMD_SM_READY ){ // ready cmd
  571. log_dbg("%s, idx:%d, state:%s, step:%d, got ready cmd, set dev aps = 0, wait and chk",
  572. __func__,idx, sm_get_szstate(sm), sm_get_step(sm));
  573. ies1000_reset_cmd(idx);
  574. ies1000_set_dev_aps(idx, 0);
  575. sm_set_step(sm, 30);
  576. sm_set_count(sm, 0);
  577. }else if( aps <= 0 ){ // aps <= 0
  578. log_dbg("%s, idx:%d, state:%s, step:%d, aps <= 0 detected, %d, set dev aps = 0, wait and chk",
  579. __func__, idx, sm_get_szstate(sm), sm_get_step(sm), aps);
  580. ies1000_set_dev_aps(idx, 0);
  581. sm_set_step(sm, 30);
  582. sm_set_count(sm, 0);
  583. }else if( ies1000_is_aps_changed(idx) ){ // new aps, set devaps and chk
  584. log_dbg("%s, idx:%d, state:%s, step:%d, new aps detected, %d -> %d, set dev aps",
  585. __func__, idx, sm_get_szstate(sm), sm_get_step(sm), last_aps, aps);
  586. ies1000_set_aps(idx, aps); // update last aps
  587. ies1000_set_dev_aps(idx, aps);
  588. }else if( ies1000_is_bsytikchk_timeout(idx) ){
  589. log_dbg("%s, idx:%d, state:%s, step:%d, bsytik timeout detected, set dev aps to 0",
  590. __func__,idx, sm_get_szstate(sm), sm_get_step(sm));
  591. ies1000_set_aps(idx, 0);
  592. }else if( ies1000_get_runstat(idx) != IES1000_RUNSTAT_DHG ){
  593. log_dbg("%s, idx:%d, state:%s, step:%d, run state != dhg detected, set dev aps to 0, goto err",
  594. __func__,idx, sm_get_szstate(sm), sm_get_step(sm));
  595. ies1000_set_dev_aps(idx, 0);
  596. sm_set_state(sm, SMST_ERR, IES1000ERR_DHG_NONDHG_DETECTED);
  597. }
  598. }else if( sm_get_step(sm) == 30 ){ // chk dev aps = 0 for readycmd
  599. if( ies1000_get_dev_aps(idx) == 0 ){
  600. log_dbg("%s, idx:%d, state:%s, step:%d, chk dev aps = 0 ok, wait and chk ap",
  601. __func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  602. sm_set_step(sm, 31);
  603. sm_set_count(sm, 0);
  604. }else{
  605. sm_inc_count(sm);
  606. if( sm_get_count(sm) >= 100 ){
  607. sm_set_state(sm, SMST_ERR, IES1000ERR_DHG_WAIT_DEVAPS0_FOR_READYCMD_TIMEOUT);
  608. log_dbg("%s, idx:%d, state:%s, step:%d, wait dev aps = 0 for readycmd timeout, goto err",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  609. }else{
  610. log_dbg("%s, idx:%d, state:%s, step:%d, waiting dev aps = 0 for readycmd, count: %d",
  611. __func__, idx, sm_get_szstate(sm), sm_get_step(sm), sm_get_count(sm));
  612. }
  613. }
  614. }else if( sm_get_step(sm) == 31 ){ // chk ap = 0 for readycmd
  615. if( ap < 2 && ap > -2 ){
  616. log_dbg("%s, idx:%d, state:%s, step:%d, chk ap ok for readycmd, %d, idlecmd sent, wait and chk run state = idle",
  617. __func__, idx, sm_get_szstate(sm), sm_get_step(sm), ap);
  618. ies1000_set_dev_idlecmd(idx);
  619. sm_set_step(sm, 32);
  620. sm_set_count(sm, 0);
  621. }else{
  622. sm_inc_count(sm);
  623. if( sm_get_count(sm) >= 100 ){
  624. log_dbg("%s, idx:%d, state:%s, step:%d, wait ap = 0 for readycmd timeout, goto err",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  625. sm_set_state(sm, SMST_ERR, IES1000ERR_DHG_WAIT_AP0_FOR_READYCMD_TIMEOUT);
  626. }else{
  627. log_dbg("%s, idx:%d, state:%s, step:%d, waiting ap = 0 for readycmd, count:%d",
  628. __func__, idx, sm_get_szstate(sm), sm_get_step(sm), sm_get_count(sm));
  629. }
  630. }
  631. }else if( sm_get_step(sm) == 32 ){ // wait run state = idle for readycmd
  632. if( ies1000_get_runstat(idx) == IES1000_RUNSTAT_IDLE ){
  633. log_dbg("%s, idx:%d, state:%s, step:%d, chk run state = idle ok, goto ready",
  634. __func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  635. sm_set_state(sm, SMST_READY, IES1000ERR_NONE);
  636. }else{
  637. sm_inc_count(sm);
  638. if( sm_get_count(sm) >= 100 ){
  639. log_dbg("%s, idx:%d, state:%s, step:%d, wait run state = idle timeout, goto err",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  640. sm_set_state(sm, SMST_ERR, IES1000ERR_DHG_WAIT_RUNSTATE_IDLE_FOR_READYCMD_TIMEOUT);
  641. }else{
  642. log_dbg("%s, idx:%d, state:%s, step:%d, waiting run state = idle for readycmd, count:%d",
  643. __func__, idx, sm_get_szstate(sm), sm_get_step(sm), sm_get_count(sm));
  644. }
  645. }
  646. }
  647. }
  648. static void ies1000_sm_chg( int idx )
  649. {
  650. struct ies1000_t* dev = &ies1000[idx];
  651. struct comm_t* comm = &ies1000[idx].comm;
  652. struct statemachine_t* sm = &ies1000[idx].sm;
  653. int aps = ies1000_get_aps(idx);
  654. int last_aps = ies1000_get_last_aps(idx);
  655. int ap = ies1000_get_ap(idx);
  656. /* chk comm state */
  657. if( comm_get_state(comm) != COMMST_NORMAL){
  658. log_dbg("%s, idx:%d, state:%s, step:%d, comm err detected, goto err",
  659. __func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  660. sm_set_state(sm, SMST_ERR, IES1000ERR_CHG_COMMERR);
  661. return;
  662. }
  663. if( sm_get_step(sm) == 0 ){ // entry
  664. log_dbg("%s, idx:%d, state:%s, step:%d, entry", __func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  665. sm_set_step(sm, 10);
  666. ies1000_reset_bsytikchk(idx);
  667. }else if( sm_get_step(sm) == 10 ){ // wait and chk
  668. if( ies1000_get_cmd(idx) == CMD_SM_READY ){
  669. log_dbg("%s, idx:%d, state:%s, step:%d, got ready cmd, set dev aps = 0",
  670. __func__,idx, sm_get_szstate(sm), sm_get_step(sm));
  671. ies1000_reset_cmd(idx);
  672. ies1000_set_dev_aps(idx, 0);
  673. sm_set_step(sm, 30);
  674. sm_set_count(sm, 0);
  675. }else if( aps >= 0 ){ // aps => 0
  676. log_dbg("%s, idx:%d, state:%s, step:%d, aps >= 0 detected, %d, set dev aps = 0, wait and chk",
  677. __func__, idx, sm_get_szstate(sm), sm_get_step(sm), aps);
  678. ies1000_set_dev_aps(idx, 0);
  679. sm_set_step(sm, 30);
  680. sm_set_count(sm, 0);
  681. }else if( ies1000_is_aps_changed(idx) ){ /* new aps, set devaps and chk */
  682. log_dbg("%s, idx:%d, state:%s, step:%d, new aps detected, %d -> %d, set dev aps",
  683. __func__, idx, sm_get_szstate(sm), sm_get_step(sm), last_aps, aps);
  684. ies1000_set_aps(idx, aps); // update last aps
  685. ies1000_set_dev_aps(idx, aps);
  686. }else if( ies1000_is_bsytikchk_timeout(idx) ){
  687. log_dbg("%s, idx:%d, state:%s, step:%d, bsytik timeout detected, set dev aps to 0",
  688. __func__,idx, sm_get_szstate(sm), sm_get_step(sm));
  689. ies1000_set_aps(idx, 0);
  690. }else if( ies1000_get_runstat(idx) != IES1000_RUNSTAT_CHG ){
  691. log_dbg("%s, idx:%d, state:%s, step:%d, run state != chg detected, set dev aps to 0, goto err",
  692. __func__,idx, sm_get_szstate(sm), sm_get_step(sm));
  693. ies1000_set_dev_aps(idx, 0);
  694. sm_set_state(sm, SMST_ERR, IES1000ERR_CHG_NONCHG_DETECTED);
  695. }
  696. }else if( sm_get_step(sm) == 30 ){ // chk dev aps = 0 for readycmd
  697. if( ies1000_get_dev_aps(idx) == 0 ){
  698. log_dbg("%s, idx:%d, state:%s, step:%d, chk dev aps = 0 ok, wait and chk ap",
  699. __func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  700. sm_set_step(sm, 31);
  701. sm_set_count(sm, 0);
  702. }else{
  703. sm_inc_count(sm);
  704. if( sm_get_count(sm) >= 100 ){
  705. sm_set_state(sm, SMST_ERR, IES1000ERR_CHG_WAIT_DEVAPS0_FOR_READYCMD_TIMEOUT);
  706. log_dbg("%s, idx:%d, state:%s, step:%d, wait dev aps = 0 for readycmd timeout, goto err",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  707. }else{
  708. log_dbg("%s, idx:%d, state:%s, step:%d, waiting dev aps = 0 for readycmd, count: %d",
  709. __func__, idx, sm_get_szstate(sm), sm_get_step(sm), sm_get_count(sm));
  710. }
  711. }
  712. }else if( sm_get_step(sm) == 31 ){ // chk ap = 0 for readycmd
  713. if( ap < 2 && ap > -2 ){
  714. log_dbg("%s, idx:%d, state:%s, step:%d, chk ap ok for readycmd, %d, idlecmd sent, wait and chk run state = idle",
  715. __func__, idx, sm_get_szstate(sm), sm_get_step(sm), ap);
  716. ies1000_set_dev_idlecmd(idx);
  717. sm_set_step(sm, 32);
  718. sm_set_count(sm, 0);
  719. }else{
  720. sm_inc_count(sm);
  721. if( sm_get_count(sm) >= 100 ){
  722. log_dbg("%s, idx:%d, state:%s, step:%d, wait ap = 0 for readycmd timeout, goto err",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  723. sm_set_state(sm, SMST_ERR, IES1000ERR_CHG_WAIT_AP0_FOR_READYCMD_TIMEOUT);
  724. }else{
  725. log_dbg("%s, idx:%d, state:%s, step:%d, waiting ap = 0 for readycmd, count:%d",
  726. __func__, idx, sm_get_szstate(sm), sm_get_step(sm), sm_get_count(sm));
  727. }
  728. }
  729. }else if( sm_get_step(sm) == 32 ){ // wait run state = idle for readycmd
  730. if( ies1000_get_runstat(idx) == IES1000_RUNSTAT_IDLE ){
  731. log_dbg("%s, idx:%d, state:%s, step:%d, chk run state = idle ok, goto ready",
  732. __func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  733. sm_set_state(sm, SMST_READY, IES1000ERR_NONE);
  734. }else{
  735. sm_inc_count(sm);
  736. if( sm_get_count(sm) >= 100 ){
  737. log_dbg("%s, idx:%d, state:%s, step:%d, wait run state = idle timeout, goto err",__func__, idx, sm_get_szstate(sm), sm_get_step(sm));
  738. sm_set_state(sm, SMST_ERR, IES1000ERR_CHG_WAIT_RUNSTATE_IDLE_FOR_READYCMD_TIMEOUT);
  739. }else{
  740. log_dbg("%s, idx:%d, state:%s, step:%d, waiting run state = idle for readycmd, count:%d",
  741. __func__, idx, sm_get_szstate(sm), sm_get_step(sm), sm_get_count(sm));
  742. }
  743. }
  744. }
  745. }
  746. void ies1000_sm( int idx )
  747. {
  748. struct ies1000_t* dev = &ies1000[idx];
  749. struct statemachine_t* sm = &dev->sm;
  750. sm_cal_timing(&dev->sm);
  751. switch( sm_get_state( sm ) ){
  752. case SMST_LAUNCH:
  753. ies1000_sm_launch( idx );
  754. break;
  755. case SMST_STDBY:
  756. ies1000_sm_stdby( idx );
  757. break;
  758. case SMST_STOP:
  759. ies1000_sm_stop( idx );
  760. break;
  761. case SMST_OFFGRID:
  762. ies1000_sm_offgrid( idx );
  763. break;
  764. case SMST_READY:
  765. ies1000_sm_ready( idx );
  766. break;
  767. case SMST_DHG:
  768. ies1000_sm_dhg( idx );
  769. break;
  770. case SMST_CHG:
  771. ies1000_sm_chg( idx );
  772. break;
  773. case SMST_ERR:
  774. ies1000_sm_err( idx );
  775. break;
  776. default:
  777. log_dbg("%s, unknown state, %d",__func__, ies1000_get_state( idx ));
  778. break;
  779. }
  780. }