/** @page shellmatta_ymodem Shellmatta ymodem To be able to pass binary files to the shellmatta there is a ymodem module implemented. The ymodem reception can be started from a shellmatta command and handles the handshaking as well as the data transmission. As the shellmatta does not use dynamic memory every packet is passed directly to the application using a callback. Only the currently received packet is stored in the shellmatta internally. In order to transmit the start characters to the sender you need to poll the shellmatta_processData() function cyclically even if no new data has been received. Do this in 0.1s - 1s periods (depending on the latency you are after). When the transmission is complete the shellmatta requires to be polled #YMODEM_POLL_NUMBER times. This ensures a short wait time to flush all unwanted bytes from the transmitter. The shellmatta_ymodem_init() function will return and the command it was called from will not be executed again. The rest of the ymodem processing will be handled by the shellmatta. The data will be passed using the callbacks registered during the start. To cancel the ymodem (e.g. timeout) just call shellmatta_ymodem_cancel() @section shellmatta_ymodem_sequence Basic sequence @startuml Application -> Shellmatta: shellmatta_ymodem_init() Shellmatta -> Host: send C to start transmission Shellmatta -> Application: return loop until ymodem transmission starts (or is canceled) Application -> Shellmatta: shellmatta_processData(null) Shellmatta -> Host: send C to start transmission end Application -> Shellmatta: shellmatta_processData(first packet) Shellmatta -> Application: packetHeader(fileSize, FileName) callback loop until shellmatta transmission is complete Host -> Shellmatta: Data transmission Shellmatta -> Application: packetRcv() callback end Shellmatta -> Application: transmissionComplete() callback @enduml While the ymodem is active no command can be executed. When the ymodem is canceled from the Host the data received afterwards will be processed as usual. @warning Ymodem cannot cooperate with optional transport layer. When the transport layer is enabled but not mandatory it is forced to stay in the mode it was when the ymodem transfer starts. When the transport layer was active it has to keep active. If it is inactive it cannot be activated during the ymodem transfer. @section shellmatta_ymodem_internal_buffer Internal buffer To save some memory you can use the shellmatta ymodem module using the internal buffer which usually is used to cache normal input before processing it. Just set the recvBuffer to NULL in #shellmatta_ymodem_init calls. @warning Ensure that your shellmattas buffer is at least #YMODEM_PACKET_SIZE_1K large to fit the ymodem packet. This is checked during initialization. @section shellmatta_ymodem_paused_mode Paused mode When the application requires time to process the currently received packet the application can call #shellmatta_ymodem_pause from the callbacks. This will prevent the shellmatta from sending the ACK to the sender. When the processing is done just call #shellmatta_ymodem_resume. @section shellmatta_ymodem_crc CRC calculation The shellmatta ymodem uses the CRC16 algorithm to secure the transmission (0x1021). By default the shellmatta crc implementation uses a lookup table to calculate the crc in a performant way. This uses quite a lot of read only memory on the device. If the memory consumption is an Issue you can switch to a slower implementation without the lookup table. This will increase CPU load quite a bit, but saves nearly 0.5K of read only memory. To enable the lookup table less CRC just define ``SHELLMATTA_YMODEM_CRC_NO_LOOKUP`` during compilation. */