2323
2424#if defined (VIRTIOCON)
2525
26- #include " openamp .h"
27- #include " openamp_log.h "
28- #include " wiring.h "
29- #include " virtio_buffer.h "
26+ #include " VirtIOSerial .h"
27+ #if !defined(VIRTIOSERIAL_NUM)
28+ #define VIRTIOSERIAL_NUM 1
29+ #endif
3030
31- VirtIOSerial SerialVirtIO;
32- void serialEventVirtIO () __attribute__((weak));
31+ VirtIOSerialObj_t *VirtIOSerial_Handle[VIRTIOSERIAL_NUM] = {NULL };
3332
34- static VIRT_UART_HandleTypeDef huart ;
35- static bool initialized = false ;
36- static bool first_message_discarded = false ;
37- static virtio_buffer_t ring ;
33+ uint32_t VirtIOSerial::VirtIOSerial_index = 0 ;
34+
35+ // Default instance
36+ VirtIOSerial SerialVirtIO ;
3837
39- void rxCallback (VIRT_UART_HandleTypeDef *huart);
38+ void serialEventVirtIO () __attribute__((weak));
39+ VirtIOSerialObj_t *get_VirtIOSerial_obj (VIRT_UART_HandleTypeDef *huart);
4040
4141void VirtIOSerial::begin (void )
4242{
43- virtio_buffer_init (&ring);
44- if (initialized) {
43+ virtio_buffer_init (&_VirtIOSerialObj. ring );
44+ if (_VirtIOSerialObj. initialized ) {
4545 return ;
4646 }
4747 if (OPENAMP_Init () != 0 ) {
4848 Error_Handler ();
4949 }
50- if (VIRT_UART_Init (&huart ) != VIRT_UART_OK) {
50+ if (VIRT_UART_Init (&_VirtIOSerialObj. handle ) != VIRT_UART_OK) {
5151 Error_Handler ();
5252 }
53+
54+ VirtIOSerial_index ++;
55+ _VirtIOSerialObj.__this = (void *)this ;
56+
5357 /* Need to register callback for message reception by channels */
54- if (VIRT_UART_RegisterCallback (&huart , VIRT_UART_RXCPLT_CB_ID, rxCallback ) != VIRT_UART_OK) {
58+ if (VIRT_UART_RegisterCallback (&_VirtIOSerialObj. handle , VIRT_UART_RXCPLT_CB_ID, rxGenericCallback ) != VIRT_UART_OK) {
5559 Error_Handler ();
5660 }
57- initialized = true ;
58- first_message_discarded = false ;
61+
62+ VirtIOSerial_Handle[VirtIOSerial_index] = &_VirtIOSerialObj;
63+ _VirtIOSerialObj.initialized = true ;
64+ _VirtIOSerialObj.first_message_discarded = false ;
5965}
6066
6167void VirtIOSerial::begin (uint32_t /* baud_count */ )
@@ -73,13 +79,13 @@ void VirtIOSerial::begin(uint32_t /* baud_count */, uint8_t /* config */)
7379void VirtIOSerial::end ()
7480{
7581 OPENAMP_DeInit ();
76- virtio_buffer_init (&ring);
77- initialized = false ;
82+ virtio_buffer_init (&_VirtIOSerialObj. ring );
83+ _VirtIOSerialObj. initialized = false ;
7884}
7985
8086int VirtIOSerial::available (void )
8187{
82- return virtio_buffer_read_available (&ring);
88+ return virtio_buffer_read_available (&_VirtIOSerialObj. ring );
8389}
8490
8591int VirtIOSerial::availableForWrite ()
@@ -91,9 +97,9 @@ int VirtIOSerial::availableForWrite()
9197
9298int VirtIOSerial::peek (void )
9399{
94- if (virtio_buffer_read_available (&ring) > 0 ) {
100+ if (virtio_buffer_read_available (&_VirtIOSerialObj. ring ) > 0 ) {
95101 uint8_t tmp;
96- virtio_buffer_peek (&ring, &tmp, 1 );
102+ virtio_buffer_peek (&_VirtIOSerialObj. ring , &tmp, 1 );
97103 return tmp;
98104 } else {
99105 return -1 ;
@@ -134,7 +140,7 @@ size_t VirtIOSerial::write(uint8_t ch)
134140// until all bytes are sent.
135141size_t VirtIOSerial::write (const uint8_t *buffer, size_t size)
136142{
137- if (VIRT_UART_Transmit (&huart , const_cast <uint8_t *>(buffer), size) == VIRT_UART_ERROR) {
143+ if (VIRT_UART_Transmit (&_VirtIOSerialObj. handle , const_cast <uint8_t *>(buffer), size) == VIRT_UART_ERROR) {
138144 // This error usually happens when rpmsg is not ready for
139145 return 0 ;
140146 }
@@ -148,26 +154,44 @@ void VirtIOSerial::flush(void)
148154 return ;
149155}
150156
151- void rxCallback (VIRT_UART_HandleTypeDef *huart)
157+ void VirtIOSerial::rxGenericCallback (VIRT_UART_HandleTypeDef *huart)
152158{
159+ VirtIOSerialObj_t *obj = get_VirtIOSerial_obj (huart);
160+ VirtIOSerial *VIOS = (VirtIOSerial *)(obj->__this );
161+
162+ VIOS->rxCallback (huart);
163+ }
164+
165+ void VirtIOSerial::rxCallback (VIRT_UART_HandleTypeDef *huart)
166+ {
167+
153168 // Linux host must send a dummy data first to finish initialization of rpmsg
154169 // on the coprocessor side. This message should be discarded.
155170 // run_arduino_gen.sh script will send dummy data: "DUMMY".
156171 // See: https://github.com/OpenAMP/open-amp/issues/182
157172 // See: run_arduino_gen.sh
158- if (!first_message_discarded) {
173+ if (!_VirtIOSerialObj. first_message_discarded ) {
159174 huart->RxXferSize = 0 ;
160- first_message_discarded = true ;
175+ _VirtIOSerialObj. first_message_discarded = true ;
161176 }
162177
163178 /* copy received msg in a variable to sent it back to master processor in main infinite loop*/
164- size_t size = min (huart->RxXferSize , virtio_buffer_write_available (&ring));
179+ size_t size = min (huart->RxXferSize , virtio_buffer_write_available (&_VirtIOSerialObj. ring ));
165180 while (size > 0 ) {
166- size -= virtio_buffer_write (&ring, huart->pRxBuffPtr , size);
181+ size -= virtio_buffer_write (&_VirtIOSerialObj. ring , huart->pRxBuffPtr , size);
167182 }
168- if (virtio_buffer_write_available (&ring) >= RPMSG_BUFFER_SIZE) {
183+ if (virtio_buffer_write_available (&_VirtIOSerialObj. ring ) >= RPMSG_BUFFER_SIZE) {
169184 MAILBOX_Notify_Rx_Buf_Free ();
170185 }
171186}
172187
188+ /* Aim of the function is to get _VirtIOSerialObj pointer using huart pointer */
189+ /* Highly inspired from magical linux kernel's "container_of" */
190+ VirtIOSerialObj_t *get_VirtIOSerial_obj (VIRT_UART_HandleTypeDef *huart)
191+ {
192+ VirtIOSerialObj_t *obj;
193+ obj = (VirtIOSerialObj_t *)((char *)huart - offsetof (VirtIOSerialObj_t, handle));
194+ return (obj);
195+ }
196+
173197#endif /* VIRTIOCON */
0 commit comments