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>
 */

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>
 */

#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>
 */

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>
 */

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>
 */

#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>
 */

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>
 */

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>
 */

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

Reply via email to