This won't be much help because I've never used UartStream...

The fact that you get a single byte would point to there being
some kind of state failure in your program that disables
subsequent receptions. In fact I would be surprised if you
really need to control the interrupt directly in your
application, so you might be inadvertently disabling the
Uart interrupt after the first byte.

Can you find a good example of UartStream usage to copy?

Or another approach would be to use I2C to talk to the PIC,
many PICs seem to support it in hardware. That might open
another can of worms on the TOS side, but it is used for
radio and sensor access on the telosb, so at least there's
some usage examples.

MS


Ronald Eliseo Reyes López wrote:
> Hello,
> 
> I need to send commands to a Pic and receive data from it in response to 
> commands sent using the Telosb Uart0 port.
> The commands reach the Pic, and interprets them, but just a few data 
> arrives at the Pic to the mote. I need to receive at least 45 bytes and 
> receives only one byte using UartStream interface.
> 
> I show the code of the project:
> 
> /**
>  * Implementacion Hal del modulo
>  * de adquisicion Mapa.
>  * @author Aldo Insfran <insfran.a...@gmail.com 
> <mailto:insfran.a...@gmail.com>>
>  */
> 
> configuration HalMapaC {
> 
>   provides interface Init as Hardware;
>   provides interface Mapa;
> 
> }
> 
> implementation {
> 
>   components HalMapaP as MapaP;
>   Mapa = MapaP;
> 
>   components HplMapaUartC as UartC;
>   MapaP.RecursoUart -> UartC;
>   MapaP.UartStream -> UartC;
> 
>   components HplMapaPinsC as PinsC;
>   MapaP.FDM -> PinsC.FDM;
> 
>   Hardware = PinsC;
> 
>   components new TimerMilliC();
>   MapaP.Retardo -> TimerMilliC;
> 
> }
> 
> /**
>  * Modulo Privado que implementa la interfaz Mapa a nivel Hal.
>  * @author Aldo Insfran <insfran.a...@gmail.com 
> <mailto:insfran.a...@gmail.com>>
>  */
> 
> #ifdef DEBUG_PRINTF
> #include "printf.h"
> #endif
> #include "Mapa.h"
> 
> #define CANT_MAX 2
> 
> module HalMapaP {
> 
>   provides interface Mapa;
> 
>   uses interface HplMsp430Interrupt as FDM;
>   uses interface Resource as RecursoUart;
>   uses interface UartStream;
>   uses interface Timer<TMilli> as Retardo;
> 
> }
> 
> implementation {
> 
>   norace bool m_es_comando = FALSE;
> 
>   norace error_t m_respuesta;
> 
>   norace uint8_t m_orden;
>   norace uint8_t m_cont = 0;
>   norace uint8_t m_sen_err = 0;
>   norace uint8_t* punt_paq;
>   norace uint16_t m_lon;
> 
>   norace mapa_tarea_t m_tarea;
>   norace paq_mapa_t* paq_med;
> 
>   void act_interrup();
>   void desact_interrup();
> 
>   error_t liberar_recurso();
> 
>   task void senalizarEventos();
> 
>   async command error_t Mapa.enviarComando( uint8_t* orden ) {
>     if( call RecursoUart.isOwner() || !call FDM.getValue() ) { return 
> EBUSY; }
>     m_orden = *orden;
>     m_tarea = S_ENVIAR;
>     return call RecursoUart.request();
>   }
> 
>   event void RecursoUart.granted() {
>     call UartStream.disableReceiveInterrupt();
> #ifdef DEBUG_PRINTF
>     printf("Recurso Concedido\n");
>     printfflush();
> #endif
>     atomic
>     switch( m_tarea ) {
>       case S_ENVIAR:
>         if( call UartStream.send( &m_orden, 1 ) != SUCCESS ) { m_sen_err 
> = 1; }
>         break;
>       case S_RECIBIR:
>         m_orden = 0xAA;
>         if( call UartStream.send( &m_orden, 1 ) != SUCCESS ) { m_sen_err 
> = 2; }
>         break;
>       default:
>         break;}
>     post senalizarEventos();
>   }
> 
>   async event void UartStream.sendDone( uint8_t* buf, uint16_t len, 
> error_t error ) {
>     atomic
>     switch( m_tarea ) {
>       case S_ENVIAR:
>         if( m_orden != *buf || error != SUCCESS || call FDM.getValue() ) 
> { m_sen_err = 1; }
>         else { m_sen_err = 3; }
>         break;
>       case S_RECIBIR:
>         if( m_orden != *buf || error != SUCCESS || call FDM.getValue() ) 
> { m_sen_err = 2; }
>         else {
>           m_sen_err = 4;
>           if( call UartStream.enableReceiveInterrupt() != SUCCESS ) { 
> m_sen_err = 2; }
>           else {
>             m_cont = 0;
>             punt_paq = (uint8_t*)paq_med;}}
>         break;
>       default:
>         break;}
>     post senalizarEventos();
>   }
> 
>   async event void UartStream.receivedByte( uint8_t byte_recibido ) {
>     atomic
>     if( m_cont != CANT_MAX )
>       *( punt_paq + m_cont++ ) = byte_recibido;
>     else {
>       m_sen_err = 5;
>       post senalizarEventos();}
> #ifdef DEBUG_PRINTF
>     printf("%d",m_cont);
>     printfflush();
> #endif
>   }
> 
>   async event void FDM.fired() {
>     atomic{
>     m_tarea = S_RECIBIR;
>     desact_interrup();
>     call RecursoUart.request();}
> #ifdef DEBUG_PRINTF
>     printf("Int_FDM\n");
>     printfflush();
> #endif
>   }
> 
>   void act_interrup() {
>     atomic{
>     call FDM.disable();
>     call FDM.clear();
>     call FDM.edge(TRUE);
>     call FDM.enable();}
> #ifdef DEBUG_PRINTF
>     printf("Int_FDM_Act\n");
>     printfflush();
> #endif
>   }
> 
>   void desact_interrup() {
>     atomic{
>     call FDM.disable();
>     call FDM.clear();}
> #ifdef DEBUG_PRINTF
>     printf("Int_FDM_Desact\n");
>     printfflush();
> #endif
>   }
> 
>   error_t liberar_recurso() {
>     atomic
>     m_respuesta = call RecursoUart.release();
> #ifdef DEBUG_PRINTF
>     if( m_respuesta == SUCCESS ) {
>       printf("Recurso Liberado\n");
>       printfflush(); }
> #endif
>     return m_respuesta;
>   }
> 
>   event void Retardo.fired() {
>   }
> 
>   task void senalizarEventos() {
>     switch( m_sen_err ) {
> #ifdef DEBUG_PRINTF
>       case 0:
>         if( m_tarea == S_ENVIAR )
>           printf("EnvCom\n");
>         else if( m_tarea == S_RECIBIR )
>           printf("EnvPet\n");
>         break;
> #endif
>       case 1:
>         signal Mapa.enviarComandoDone( FAIL );
>         liberar_recurso();
>         break;
>       case 2:
>         signal Mapa.medicionesListas( NULL, 0, FAIL );
>         liberar_recurso();
>         break;
>       case 3:
>         act_interrup();
>         signal Mapa.enviarComandoDone( SUCCESS );
>         liberar_recurso();
>       case 4:
> #ifdef DEBUG_PRINTF
>         printf("SendDone,%x\n", m_orden);
>         printfflush();
> #endif
>         break;
>       case 5:
>         signal Mapa.medicionesListas( (uint8_t*)paq_med, m_cont, SUCCESS );
>           call UartStream.disableReceiveInterrupt();
>           liberar_recurso();
>         break;
>       default:
>         break;}
>     m_sen_err = 0;
>   }
> 
>   async event void UartStream.receiveDone( uint8_t* med, uint16_t lon, 
> error_t result ) { }
> 
>   default async event void Mapa.enviarComandoDone( error_t result ) { }
>   default async event void Mapa.medicionesListas( uint8_t* mediciones, 
> uint16_t lon, error_t result ) { }
> 
> }
> 
> typedef enum {
>   S_ENVIAR,
>   S_RECIBIR,
>  } mapa_tarea_t;
> 
> typedef struct {
>   uint8_t hora[11];
> } gps_utc_t;
> 
> typedef struct {
>   uint8_t latitud[12];
> } gps_lat_t;
> 
> typedef struct {
>   uint8_t longitud[13];
> } gps_long_t;
> 
> typedef struct {
>   gps_utc_t hora_utc;
>   gps_lat_t latitud;
>   gps_long_t longitud;
> } mapa_gps_t;
> 
> typedef struct {
>   uint32_t valor;
>   uint8_t tipo;
> } mapa_veloc_t;
> 
> typedef struct {
>   uint32_t presion;
>   mapa_veloc_t veloc;
>   mapa_gps_t posc;
> } paq_mapa_t;
> 
> /**
>  * Interfaz a nivel Hal del modulo de adquisicion.
>  * @author Aldo Insfran <insfran.a...@gmail.com 
> <mailto:insfran.a...@gmail.com>>
>  */
> 
> interface Mapa {
> 
>   /**
>    * Envia el una orden al Mapa
>    *
>    * @return SUCCESS if the request completed successfully, FAIL
>    * otherwise.
>    */
>   async command error_t enviarComando( uint8_t* orden );
>  
>  /**
>    * Senala el resultado del envio de la orden
>    *
>    * @param result SUCCESS if the request completed successfully, FAIL 
> otherwise.
>    * @param orden_enviada orden enviada al Mapa
>    */
>   async event void enviarComandoDone( error_t result );
> 
>  /**
>    * Devuelve las mediciones del MAPA
>    * @param mediciones puntero a la estructura que contiene las mediciones
>    */
>   async event void medicionesListas( uint8_t* mediciones, uint16_t 
> longitud, error_t respuesta );
> 
> }
> 
> /**
>  * Programa de Aplicacion para el Driver del
>  * Recurso Mapa
>  * @author Aldo Insfran <insfran.a...@gmail.com 
> <mailto:insfran.a...@gmail.com>>
>  */
> 
> configuration MapaAppC {
> }
> 
> implementation {
> 
>   components MapaC;
> 
>   components MainC;
>   MapaC.Boot -> MainC;
> 
>   components HalMapaC; 
>   MapaC.ModAdq -> HalMapaC;
>   MapaC.Hardware -> HalMapaC;
> 
>   components LedsC;
>   MapaC.Leds -> LedsC;
> 
>   components new TimerMilliC();
>   MapaC.Temp -> TimerMilliC;
> 
>   components new UdpSocketC() as RedSensado;
>   MapaC.SocketRedSensado -> RedSensado;
> 
>   components IPDispatchC;
>   MapaC.PilaIP -> IPDispatchC;
> 
> }
> 
> /**
>  * Programa de Aplicacion para el Driver del
>  * Recurso Mapa.
>  * @author Aldo Insfran <insfran.a...@gmail.com 
> <mailto:insfran.a...@gmail.com>>
>  */
> 
> #include <lib6lowpan.h>
> 
> module MapaC {
>   uses {
> 
>     interface Boot;
>     interface Init as Hardware;
>     interface Mapa as ModAdq;
>     interface Leds;
>     interface Timer<TMilli> as Temp;
>     interface SplitControl as PilaIP;
>     interface UDP as SocketRedSensado;
> 
>   }
> }
> implementation {
> 
>   uint8_t paq_med;
>   uint8_t orden = 0x30;
>   uint8_t* punt_orden = &orden;
> 
>   event void Boot.booted() {
>     call PilaIP.start(); }
> 
>   event void PilaIP.startDone( error_t error ) {
>     call Leds.led1On();
>     call Temp.startOneShot(5120);
>   }
> 
>   event void PilaIP.stopDone( error_t error ) {
>     call Hardware.init();
>     if( call ModAdq.enviarComando( punt_orden ) == SUCCESS ) {
>       call Leds.led1Off();
>       call Temp.startOneShot(30720); }}
> 
>   event void SocketRedSensado.recvfrom( struct sockaddr_in6 *remitente, 
> void *datos, uint16_t longitud, struct ip_metadata *meta ) { }
> 
>   event void Temp.fired() {
>     call PilaIP.stop(); }
> 
>   async event void ModAdq.enviarComandoDone( error_t result ) {
>     if( result != SUCCESS )
>       call Leds.led0On();
>   }
> 
>   async event void ModAdq.medicionesListas( uint8_t* med, uint16_t lon, 
> error_t result ) {
>     atomic
>     paq_med = *med;
>     call PilaIP.start();
>   }
> 
> }
> 
> /**
>  * Abstraccion Uart para el modulo de adquisicion.
>  *
>  * @author Aldo Insfran <insfran.a...@gmail.com 
> <mailto:insfran.a...@gmail.com>>
>  */
> 
> interface MapaUart {
> 
>   /**
>    * Envia el comando 'orden' a traves del Uart0
>    *
>    * @return SUCCESS if the request completed successfully, FAIL
>    * otherwise.
>    */
>   async command error_t enviarComando( uint8_t orden );
>  
>  /**
>    * Envia el comando 'orden' a traves del Uart0
>    *
>    * @return SUCCESS if the request completed successfully, FAIL
>    * otherwise.
>    */
>   async event void enviarComandoDone( error_t error, uint8_t 
> orden_enviada, uint8_t respuesta );
> 
> }
> 
> /**
>  * Implementacion de la abstraccion del bus Uart para el modulo
>  * de adquisicion Mapa.
>  *
>  * @author Aldo Insfran <insfran.a...@gmail.com 
> <mailto:insfran.a...@gmail.com>>
>  */
> 
> configuration MapaUartC {
> 
>   provides interface Init;
>   provides interface Resource;
>   provides interface MapaUart;
> 
> }
> 
> implementation {
> 
>   components MapaUartP as UartP;
>   Init = UartP;
>   Resource = UartP.RecursoCliente;
>   MapaUart = UartP;
> 
>   components HplMapaUartC as UartC;
>   UartP.RecursoUart -> UartC;
>   UartP.UartByte -> UartC;
>   UartP.UartStream -> UartC;
> 
>   components HplMapaPinsC as PinsC;
>   UartP.FDM -> PinsC.FDM;
>   UartP.InterrupcionFDM -> PinsC.InterrupcionFDM;
> 
> }
> 
> /**
>  * @author Aldo Insfran <insfran.a...@gmail.com 
> <mailto:insfran.a...@gmail.com>>
>  */
> 
> module MapaUartP {
> 
>   provides interface Init;
>   provides interface Resource as RecursoCliente;
>   provides interface MapaUart as Uart;
> 
>   uses interface Resource as RecursoUart;
>   uses interface GeneralIO as FDM;
>   uses interface GpioInterrupt as InterrupcionFDM;
>   uses interface UartByte;
>   uses interface UartStream;
> 
> }
> 
> implementation {
> 
>   enum {
>     CRC_BUF_SIZE = 16,
>   };
> 
>   typedef enum {
>     S_READ = 0x3,
>     S_PAGE_PROGRAM = 0x2,
>     S_SECTOR_ERASE = 0xd8,
>     S_BULK_ERASE = 0xc7,
>     S_WRITE_ENABLE = 0x6,
>     S_POWER_ON = 0xab,
>     S_DEEP_SLEEP = 0xb9,
>   } stm25p_cmd_t;
> 
>   norace uint8_t m_cmd[ 4 ];
> 
>   norace bool m_is_writing = FALSE;
>   norace bool m_computing_crc = FALSE;
> 
>   norace stm25p_addr_t m_addr;
>   norace uint8_t* m_buf;
>   norace stm25p_len_t m_len;
>   norace stm25p_addr_t m_cur_addr;
>   norace stm25p_len_t m_cur_len;
>   norace uint8_t m_crc_buf[ CRC_BUF_SIZE ];
>   norace uint16_t m_crc;
> 
>   error_t newRequest( bool write, stm25p_len_t cmd_len );
>   void signalDone( error_t error );
> 
>   uint8_t sendCmd( uint8_t cmd, uint8_t len ) {
> 
>     uint8_t tmp = 0;
>     int i;
> 
>     call CSN.clr();
>     for ( i = 0; i < len; i++ )
>       tmp = call SpiByte.write( cmd );
>     call CSN.set();
> 
>     return tmp;
> 
>   }
> 
>   command error_t Init.init() {
>     call CSN.makeOutput();
>     call Hold.makeOutput();
>     call CSN.set();
>     call Hold.set();
>     return SUCCESS;
>   }
> 
>   async command error_t ClientResource.request() {
>     return call SpiResource.request();
>   }
> 
>   async command error_t ClientResource.immediateRequest() {
>     return call SpiResource.immediateRequest();
>   }
>  
>   async command error_t ClientResource.release() {
>     return call SpiResource.release();
>   }
> 
>   async command uint8_t ClientResource.isOwner() {
>     return call SpiResource.isOwner();
>   }
> 
>   stm25p_len_t calcReadLen() {
>     return ( m_cur_len < CRC_BUF_SIZE ) ? m_cur_len : CRC_BUF_SIZE;
>   } 
> 
>   async command error_t Spi.powerDown() {
>     sendCmd( S_DEEP_SLEEP, 1 );
>     return SUCCESS;
>   }
> 
>   async command error_t Spi.powerUp() {
>     sendCmd( S_POWER_ON, 5 );
>     return SUCCESS;
>   }
> 
>   async command error_t Spi.read( stm25p_addr_t addr, uint8_t* buf,
>                   stm25p_len_t len ) {
>     m_cmd[ 0 ] = S_READ;
>     m_addr = addr;
>     m_buf = buf;
>     m_len = len;
>     return newRequest( FALSE, 4 );
>   }
> 
>   async command error_t Spi.computeCrc( uint16_t crc, stm25p_addr_t addr,
>                     stm25p_len_t len ) {
>     m_computing_crc = TRUE;
>     m_crc = crc;
>     m_addr = m_cur_addr = addr;
>     m_len = m_cur_len = len;
>     return call Spi.read( addr, m_crc_buf, calcReadLen() );
>   }
>  
>   async command error_t Spi.pageProgram( stm25p_addr_t addr, uint8_t* buf,
>                      stm25p_len_t len ) {
>     m_cmd[ 0 ] = S_PAGE_PROGRAM;
>     m_addr = addr;
>     m_buf = buf;
>     m_len = len;
>     return newRequest( TRUE, 4 );
>   }
> 
>   async command error_t Spi.sectorErase( uint8_t sector ) {
>     m_cmd[ 0 ] = S_SECTOR_ERASE;
>     m_addr = (stm25p_addr_t)sector << STM25P_SECTOR_SIZE_LOG2;
>     return newRequest( TRUE, 4 );
>   }
> 
>   async command error_t Spi.bulkErase() {
>     m_cmd[ 0 ] = S_BULK_ERASE;
>     return newRequest( TRUE, 1 );
>   }
> 
>   error_t newRequest( bool write, stm25p_len_t cmd_len ) {
>     m_cmd[ 1 ] = m_addr >> 16;
>     m_cmd[ 2 ] = m_addr >> 8;
>     m_cmd[ 3 ] = m_addr;
>     if ( write )
>       sendCmd( S_WRITE_ENABLE, 1 );
>     call CSN.clr();
>     call SpiPacket.send( m_cmd, NULL, cmd_len );
>     return SUCCESS;
>   }
> 
>   void releaseAndRequest() {
>     call SpiResource.release();
>     call SpiResource.request();
>   }
> 
>   async event void SpiPacket.sendDone( uint8_t* tx_buf, uint8_t* rx_buf,
>                        uint16_t len, error_t error ) {
> 
>     int i;
> 
>     switch( m_cmd[ 0 ] ) {
> 
>     case S_READ:
>       if ( tx_buf == m_cmd ) {
>     call SpiPacket.send( NULL, m_buf, m_len );
>     break;
>       }
>       else if ( m_computing_crc ) {
>     for ( i = 0; i < len; i++ )
>       m_crc = crcByte( m_crc, m_crc_buf[ i ] );
>     m_cur_addr += len;
>     m_cur_len -= len;
>     if ( m_cur_len ) {
>       call SpiPacket.send( NULL, m_crc_buf, calcReadLen() );
>       break;
>     }
>       }
>       call CSN.set();
>       signalDone( SUCCESS );
>       break;
> 
>     case S_PAGE_PROGRAM:
>       if ( tx_buf == m_cmd ) {
>     call SpiPacket.send( m_buf, NULL, m_len );
>     break;
>       }
>       // fall through
>      
>     case S_SECTOR_ERASE: case S_BULK_ERASE:
>       call CSN.set();
>       m_is_writing = TRUE;
>       releaseAndRequest();
>       break;
> 
>     default:
>       break;
> 
>     }
> 
>   }
> 
>   event void SpiResource.granted() {
> 
>     if ( !m_is_writing )
>       signal ClientResource.granted();
>     else if ( sendCmd( 0x5, 2 ) & 0x1 )
>       releaseAndRequest();
>     else
>       signalDone( SUCCESS );
> 
>   }
> 
>   void signalDone( error_t error ) {
>     m_is_writing = FALSE;
>     switch( m_cmd[ 0 ] ) {
>     case S_READ:
>       if ( m_computing_crc ) {
>     m_computing_crc = FALSE;
>     signal Spi.computeCrcDone( m_crc, m_addr, m_len, error );
>       }
>       else {
>     signal Spi.readDone( m_addr, m_buf, m_len, error );
>       }
>       break;
>     case S_PAGE_PROGRAM:
>       signal Spi.pageProgramDone( m_addr, m_buf, m_len, error );
>       break;
>     case S_SECTOR_ERASE:
>       signal Spi.sectorEraseDone( m_addr >> STM25P_SECTOR_SIZE_LOG2, 
> error );
>       break;
>     case S_BULK_ERASE:
>       signal Spi.bulkEraseDone( error );
>       break;
>     }
>   }
> }
> 
> 
> 
> 
> 
> ------------------------------------------------------------------------
> 
> _______________________________________________
> Tinyos-help mailing list
> Tinyos-help@millennium.berkeley.edu
> https://www.millennium.berkeley.edu/cgi-bin/mailman/listinfo/tinyos-help
_______________________________________________
Tinyos-help mailing list
Tinyos-help@millennium.berkeley.edu
https://www.millennium.berkeley.edu/cgi-bin/mailman/listinfo/tinyos-help

Reply via email to