diff options
Diffstat (limited to 'src/drivers')
| -rw-r--r-- | src/drivers/ao_radio_master.c | 112 | ||||
| -rw-r--r-- | src/drivers/ao_radio_slave.c | 90 | 
2 files changed, 101 insertions, 101 deletions
diff --git a/src/drivers/ao_radio_master.c b/src/drivers/ao_radio_master.c index bfbcb1f8..73ac3c03 100644 --- a/src/drivers/ao_radio_master.c +++ b/src/drivers/ao_radio_master.c @@ -22,13 +22,16 @@  static __xdata struct ao_radio_spi_reply	ao_radio_spi_reply;  static __xdata struct ao_radio_spi_request	ao_radio_spi_request; -static volatile __xdata uint8_t			ao_radio_done = 1; +static volatile __xdata uint8_t			ao_radio_wait_mode; +static volatile __xdata uint8_t			ao_radio_done = 0; +static volatile __xdata uint8_t			ao_radio_ready = 1;  static __xdata uint8_t				ao_radio_mutex; +static __xdata uint8_t				ao_radio_aes_seq;  __xdata int8_t					ao_radio_cmac_rssi;  #if 0 -#define PRINTD(...) do { printf ("\r%s: ", __func__); printf(__VA_ARGS__); flush(); } while(0) +#define PRINTD(...) do { printf ("\r%5u %s: ", ao_tick_count, __func__); printf(__VA_ARGS__); flush(); } while(0)  #else  #define PRINTD(...)   #endif @@ -36,24 +39,18 @@ __xdata int8_t					ao_radio_cmac_rssi;  static void  ao_radio_isr(void)  { -	ao_exti_disable(AO_RADIO_INT_PORT, AO_RADIO_INT_PIN); -	ao_radio_done = 1; -	ao_wakeup((void *) &ao_radio_done); -} - -static void -ao_radio_master_delay(void) -{ -//	uint16_t	i; -//	for (i = 0; i < 1000; i++) -//		ao_arch_nop(); -	ao_delay(1); +	if (ao_gpio_get(AO_RADIO_INT_PORT, AO_RADIO_INT_PIN, AO_RADIO_INT)) { +		ao_radio_ready = 1; +		ao_wakeup((void *) &ao_radio_ready); +	} else { +		ao_radio_done = 1; +		ao_wakeup((void *) &ao_radio_done); +	}  }  static void  ao_radio_master_start(void)  { -	ao_radio_master_delay();  	ao_spi_get_bit(AO_RADIO_CS_PORT, AO_RADIO_CS_PIN, AO_RADIO_CS,  		       AO_RADIO_SPI_BUS,  		       AO_SPI_SPEED_200kHz); @@ -64,32 +61,50 @@ ao_radio_master_stop(void)  {  	ao_spi_put_bit(AO_RADIO_CS_PORT, AO_RADIO_CS_PIN, AO_RADIO_CS,  		       AO_RADIO_SPI_BUS); -//	ao_delay(1);  }  static uint8_t  ao_radio_master_send(void)  { -	if (!ao_radio_done) -		printf ("radio not done in ao_radio_master_send\n"); +	uint8_t	ret; +  	PRINTD("send %d\n", ao_radio_spi_request.len);  	ao_radio_done = 0; -	ao_exti_enable(AO_RADIO_INT_PORT, AO_RADIO_INT_PIN); + +	/* Wait for radio chip to be ready for a command +	 */ + +	PRINTD("Waiting radio ready\n"); +	cli(); +	ao_radio_ready = ao_gpio_get(AO_RADIO_INT_PORT, +				     AO_RADIO_INT_PIN, AO_RADIO_INT); +	ret = 0; +	while (!ao_radio_ready) { +		ret = ao_sleep((void *) &ao_radio_ready); +		if (ret) +			break; +	} +	sei(); +	if (ret) +		return 0; + +	PRINTD("radio_ready %d radio_done %d\n", ao_radio_ready, ao_radio_done); + +	/* Send the command +	 */ +	ao_radio_wait_mode = 0;  	ao_radio_master_start();  	ao_spi_send(&ao_radio_spi_request,  		    ao_radio_spi_request.len,  		    AO_RADIO_SPI_BUS);  	ao_radio_master_stop(); +	PRINTD("waiting for send done %d\n", ao_radio_done);  	cli();  	while (!ao_radio_done) -		if (ao_sleep((void *) &ao_radio_done)) { -			printf ("ao_radio_master awoken\n"); +		if (ao_sleep((void *) &ao_radio_done))  			break; -		}  	sei(); -	PRINTD ("sent, radio done %d\n", ao_radio_done); -	if (!ao_radio_done) -		printf ("radio didn't finish after ao_radio_master_send\n"); +	PRINTD ("sent, radio done %d isr_0 %d isr_1 %d\n", ao_radio_done, isr_0_count, isr_1_count);  	return ao_radio_done;  } @@ -112,15 +127,6 @@ ao_radio_put(void)  static void  ao_radio_get_data(__xdata void *d, uint8_t size)  { -	uint8_t	ret; - -	PRINTD ("send fetch req\n"); -	ao_radio_spi_request.len = AO_RADIO_SPI_REQUEST_HEADER_LEN; -	ao_radio_spi_request.request = AO_RADIO_SPI_RECV_FETCH; -	ao_radio_spi_request.recv_len = size; -	ret = ao_radio_master_send(); -	PRINTD ("fetch req sent %d\n", ret); -  	PRINTD ("fetch\n");  	ao_radio_master_start();  	ao_spi_recv(&ao_radio_spi_reply, @@ -167,21 +173,17 @@ ao_radio_recv(__xdata void *d, uint8_t size)  		return 0;  	}  	ao_radio_get_data(d, size); -  	recv = ao_radio_spi_reply.status; -  	ao_radio_put();  	return recv;  } -int8_t -ao_radio_cmac_send(__xdata void *packet, uint8_t len) __reentrant +static void +ao_radio_cmac_set_key(void)  { -	if (len > AO_CMAC_MAX_LEN) -		return AO_RADIO_CMAC_LEN_ERROR; - -	PRINTD ("cmac_send: send %d\n", len); +	if (ao_radio_aes_seq == ao_config_aes_seq) +		return;  	/* Set the key.  	 */  	PRINTD ("set key\n"); @@ -190,6 +192,18 @@ ao_radio_cmac_send(__xdata void *packet, uint8_t len) __reentrant  	ao_radio_master_send();  	ao_radio_put();  	PRINTD ("key set\n"); +	ao_radio_aes_seq = ao_config_aes_seq; +} + +int8_t +ao_radio_cmac_send(__xdata void *packet, uint8_t len) __reentrant +{ +	if (len > AO_CMAC_MAX_LEN) +		return AO_RADIO_CMAC_LEN_ERROR; + +	ao_radio_cmac_set_key(); + +	PRINTD ("cmac_send: send %d\n", len);  	/* Send the data  	 */ @@ -212,21 +226,14 @@ ao_radio_cmac_recv(__xdata void *packet, uint8_t len, uint16_t timeout) __reentr  	if (len > AO_CMAC_MAX_LEN)  		return AO_RADIO_CMAC_LEN_ERROR; -	/* Set the key. -	 */ -	PRINTD ("setting key\n"); -	ao_radio_get(AO_RADIO_SPI_CMAC_KEY, AO_AES_LEN); -	ao_radio_spi_request.timeout = timeout; -	ao_xmemcpy(&ao_radio_spi_request.payload, &ao_config.aes_key, AO_AES_LEN); -	recv = ao_radio_master_send(); -	ao_radio_put(); -	PRINTD ("key set: %d\n", recv); +	ao_radio_cmac_set_key();  	/* Recv the data  	 */  	PRINTD ("queuing recv\n");  	ao_radio_get(AO_RADIO_SPI_CMAC_RECV, 0);  	ao_radio_spi_request.recv_len = len; +	ao_radio_spi_request.timeout = timeout;  	recv = ao_radio_master_send();  	PRINTD ("recv queued: %d\n", recv);  	if (!recv) { @@ -300,7 +307,8 @@ ao_radio_init(void)  	ao_enable_port(AO_RADIO_INT_PORT);  	ao_exti_setup(AO_RADIO_INT_PORT,  		      AO_RADIO_INT_PIN, -		      AO_EXTI_MODE_FALLING, +		      AO_EXTI_MODE_RISING|AO_EXTI_MODE_FALLING,  		      ao_radio_isr); +	ao_exti_enable(AO_RADIO_INT_PORT, AO_RADIO_INT_PIN);  	ao_cmd_register(&ao_radio_cmds[0]);  } diff --git a/src/drivers/ao_radio_slave.c b/src/drivers/ao_radio_slave.c index ab23894f..9a01bbfa 100644 --- a/src/drivers/ao_radio_slave.c +++ b/src/drivers/ao_radio_slave.c @@ -23,54 +23,69 @@ static __xdata struct ao_radio_spi_reply ao_radio_spi_reply;  static __xdata struct ao_radio_spi_request ao_radio_spi_request; -static __xdata uint8_t	ao_radio_spi_recv_request; -static __xdata uint8_t	ao_radio_spi_recv_len; -static __xdata uint16_t	ao_radio_spi_recv_timeout; +static __xdata uint8_t	slave_state;  static void -ao_radio_slave_signal(void) +ao_radio_slave_low(void)  { +	uint16_t	i; + +	if (slave_state != 1) +		ao_panic(1); +	ao_led_toggle(AO_LED_GREEN);  	ao_gpio_set(AO_RADIO_SLAVE_INT_PORT, AO_RADIO_SLAVE_INT_BIT, AO_RADIO_SLAVE_INT_PIN, 0); -	ao_arch_nop(); -	ao_arch_nop(); -	ao_arch_nop(); +	for (i = 0; i < 1000; i++) +		ao_arch_nop(); +	slave_state = 0; +} + +static void +ao_radio_slave_high(void) +{ +	if (slave_state != 0) +		ao_panic(2); +	ao_led_toggle(AO_LED_RED);  	ao_gpio_set(AO_RADIO_SLAVE_INT_PORT, AO_RADIO_SLAVE_INT_BIT, AO_RADIO_SLAVE_INT_PIN, 1); +	slave_state = 1;  }  static void  ao_radio_slave_spi(void)  { -	uint8_t	need_signal = 0; -  	ao_spi_get_slave(AO_RADIO_SLAVE_BUS);  	for (;;) {  		ao_spi_recv(&ao_radio_spi_request,  			    (2 << 13) | sizeof (ao_radio_spi_request),  			    AO_RADIO_SLAVE_BUS); -		if (need_signal) { -			ao_radio_slave_signal(); -			need_signal = 0; -		} +		ao_radio_slave_high();  		ao_spi_recv_wait();  		switch (ao_radio_spi_request.request) {  		case AO_RADIO_SPI_RECV: -		case AO_RADIO_SPI_CMAC_RECV: + +			/* XXX monitor CS to interrupt the receive */ +  			ao_config.radio_setting = ao_radio_spi_request.setting; -			ao_radio_spi_recv_request = ao_radio_spi_request.request; -			ao_radio_spi_recv_len = ao_radio_spi_request.recv_len; -			ao_radio_spi_recv_timeout = ao_radio_spi_request.timeout; -			ao_wakeup(&ao_radio_spi_recv_len); +			ao_radio_spi_reply.status = ao_radio_recv(&ao_radio_spi_reply.payload, +								  ao_radio_spi_request.recv_len); +			ao_radio_spi_reply.rssi = 0; +			ao_spi_send(&ao_radio_spi_reply, +				    AO_RADIO_SPI_REPLY_HEADER_LEN + ao_radio_spi_request.recv_len, +				    AO_RADIO_SLAVE_BUS); +			ao_radio_slave_low(); +			ao_spi_send_wait();  			continue; -		case AO_RADIO_SPI_RECV_FETCH: +		case AO_RADIO_SPI_CMAC_RECV: +			ao_config.radio_setting = ao_radio_spi_request.setting; +			ao_radio_spi_reply.status = ao_radio_cmac_recv(&ao_radio_spi_reply.payload, +								       ao_radio_spi_request.recv_len, +								       ao_radio_spi_request.timeout); +			ao_radio_spi_reply.rssi = ao_radio_cmac_rssi;  			ao_spi_send(&ao_radio_spi_reply, -				    ao_radio_spi_request.recv_len, +				    AO_RADIO_SPI_REPLY_HEADER_LEN + ao_radio_spi_request.recv_len,  				    AO_RADIO_SLAVE_BUS); -			ao_radio_slave_signal(); +			ao_radio_slave_low();  			ao_spi_send_wait();  			continue; -		case AO_RADIO_SPI_RECV_ABORT: -			ao_radio_recv_abort(); -			break;  		case AO_RADIO_SPI_SEND:  			ao_config.radio_setting = ao_radio_spi_request.setting;  			ao_radio_send(&ao_radio_spi_request.payload, @@ -96,38 +111,15 @@ ao_radio_slave_spi(void)  			ao_radio_test(0);  			break;  		} -		need_signal = 1; -	} -} - -static void -ao_radio_slave_recv(void) -{ -	uint8_t	len; -	for (;;) { -		while (!ao_radio_spi_recv_len) -			ao_sleep(&ao_radio_spi_recv_len); -		len = ao_radio_spi_recv_len; -		ao_radio_spi_recv_len = 0; -		if (ao_radio_spi_recv_request == AO_RADIO_SPI_RECV) { -			ao_radio_spi_reply.status = ao_radio_recv(&ao_radio_spi_reply.payload, len); -			ao_radio_spi_reply.rssi = 0; -		} else { -			ao_radio_spi_reply.status = ao_radio_cmac_recv(&ao_radio_spi_reply.payload, len, -								       ao_radio_spi_recv_timeout); -			ao_radio_spi_reply.rssi = ao_radio_cmac_rssi; -		} -		ao_radio_slave_signal(); +		ao_radio_slave_low();  	}  }  static __xdata struct ao_task ao_radio_slave_spi_task; -static __xdata struct ao_task ao_radio_slave_recv_task;  void  ao_radio_slave_init(void)  {  	ao_add_task(&ao_radio_slave_spi_task, ao_radio_slave_spi, "radio_spi"); -	ao_add_task(&ao_radio_slave_recv_task, ao_radio_slave_recv, "radio_recv"); -	ao_enable_output(AO_RADIO_SLAVE_INT_PORT, AO_RADIO_SLAVE_INT_BIT, AO_RADIO_SLAVE_INT_PIN, 1); +	ao_enable_output(AO_RADIO_SLAVE_INT_PORT, AO_RADIO_SLAVE_INT_BIT, AO_RADIO_SLAVE_INT_PIN, 0);  }  | 
