-
Notifications
You must be signed in to change notification settings - Fork 37
MRF24WG Programming Interface
MRF24WG0MA is an Wi-Fi transceiver module from Microchip. Unfortunately, the programming interface is not documented in the datasheet. All the below information had been extracted from the opensource Digilent library deIPcK.
MRF24WG0MA is connected to the host microcontroller via SPI interface, with /CS and /INT signals. According to the datasheet, the SPI SCK frequency can be up to 25 MHz. Data is clocked in on the first rising edge of the clock after /CS is asserted. Data is placed on the bus MSB first.
SPI transactions consist of address byte and one or more data bytes.
Write 8-bit register:
__ __
/CS \_________________________________________________________________/
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
SCK_____/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \___
___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___ ___
SI ___\_______/___X___X___X___X___X___X___X___X___X___X___X___X___X___X___
0 0 A A A A A A V V V V V V V V
Read 8-bit register:
__ __
/CS \_________________________________________________________________/
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
SCK_____/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \_/ \___
___ _______ ___ ___ ___ ___ _______________________________________
SI ___\___/ \___X___X___X___X___X___/
0 1 A A A A A A
_______________________________________ ___ ___ ___ ___ ___ ___ ___ ___
SO \___X___X___X___X___X___X___X___X___
V V V V V V V V
Here value AAAAAA specify a 6-bit address of the register, and VVVVVVVV is a value. For 16-bit registers, the value contains 16 bits.
| Register | Address | Size | Description |
|---|---|---|---|
| INTR | 0x01 | 8-bit | 1st level interrupt flags |
| MASK | 0x02 | 8-bit | 1st level interrupt mask |
| RAW2_DATA | 0x06 | 8-bit | RAW2 data - mgmt rx |
| RAW3_DATA | 0x07 | 8-bit | RAW3 data - mgmt tx |
| RAW4_DATA | 0x08 | 8-bit | RAW4 data - scratch tx/rx |
| RAW5_DATA | 0x09 | 8-bit | RAW5 data |
| RAW4_CTRL0 | 0x0a | 16-bit | RAW4 control0 - scratch tx/rx |
| RAW4_CTRL1 | 0x0b | 16-bit | RAW4 control1 - scratch tx/rx |
| RAW4_INDEX | 0x0c | 16-bit | RAW4 index - scratch tx/rx |
| RAW4_STATUS | 0x0d | 16-bit | RAW4 status - scratch tx/rx |
| RAW5_CTRL0 | 0x0e | 16-bit | RAW5 control0 |
| RAW5_CTRL1 | 0x0f | 16-bit | RAW5 control1 |
| MAILBOX0_HI | 0x10 | 16-bit | Mailbox0 upper half |
| MAILBOX0_LO | 0x12 | 16-bit | Mailbox0 lower half |
| RAW2_CTRL0 | 0x18 | 16-bit | RAW2 control0 - mgmt rx |
| RAW2_CTRL1 | 0x19 | 16-bit | RAW2 control1 - mgmt rx |
| RAW2_INDEX | 0x1a | 16-bit | RAW2 index - mgmt rx |
| RAW2_STATUS | 0x1b | 16-bit | RAW2 status - mgmt rx |
| RAW3_CTRL0 | 0x1c | 16-bit | RAW3 control0 - mgmt tx |
| RAW3_CTRL1 | 0x1d | 16-bit | RAW3 control0 - mgmt tx |
| RAW3_INDEX | 0x1e | 16-bit | RAW3 index - mgmt tx |
| RAW3_STATUS | 0x1f | 16-bit | RAW3 status - mgmt tx |
| RAW0_DATA | 0x20 | 8-bit | RAW0 data - data rx |
| RAW1_DATA | 0x21 | 8-bit | RAW1 data - data tx |
| RAW5_INDEX | 0x22 | 16-bit | RAW5 index |
| RAW5_STATUS | 0x23 | 16-bit | RAW5 status |
| RAW0_CTRL0 | 0x25 | 16-bit | RAW0 control0 - data rx |
| RAW0_CTRL1 | 0x26 | 16-bit | RAW0 control1 - data rx |
| RAW0_INDEX | 0x27 | 16-bit | RAW0 index - data rx |
| RAW0_STATUS | 0x28 | 16-bit | RAW0 status - data rx |
| RAW1_CTRL0 | 0x29 | 16-bit | RAW1 control0 - data tx |
| RAW1_CTRL1 | 0x2a | 16-bit | RAW1 control1 - data tx |
| RAW1_INDEX | 0x2b | 16-bit | RAW1 index - data tx |
| RAW1_STATUS | 0x2c | 16-bit | RAW1 status - data tx |
| INTR2 | 0x2d | 16-bit | 2nd level interrupt flags |
| MASK2 | 0x2e | 16-bit | 2nd level interrupt mask |
| WFIFO_BCNT0 | 0x2f | 16-bit | Available write size for fifo 0 - data tx |
| WFIFO_BCNT1 | 0x31 | 16-bit | Available write size for fifo 1 - mgmt tx |
| RFIFO_BCNT0 | 0x33 | 16-bit | Number of bytes in read fifo 0 - data rx |
| RFIFO_BCNT1 | 0x35 | 16-bit | Number of bytes in read fifo 1 - mgmt rx |
| RESET | 0x3c | 16-bit | Reset and analog SPI |
| PSPOLL | 0x3d | 16-bit | Control low power mode |
| ADDR | 0x3e | 16-bit | Move the data window |
| DATA | 0x3f | 16-bit | Read or write address-indexed register |
Registers ADDR and DATA allow indirect access to additional 16-bit registers:
| Register | Address | Description |
|---|---|---|
| HW_STATUS | 0x2a | Hardware status, read only |
| CONFIG_CONTROL0 | 0x2e | Used to initiate Hard reset |
| WAKE_CONTROL | 0x2f | |
| SCRATCHPAD0 | 0x3d | Scratchpad |
| SCRATCHPAD1 | 0x3e | Read to determine when low power is done |
| PSPOLL_CONFIG | 0x40 | |
| XTAL_SETTLE_TIME | 0x41 |
In the LiteBSD driver for MRF24WG, several low-level functions provide access to SPI registers:
unsigned mrf_read_byte(unsigned regno);
void mrf_write_byte(unsigned regno, unsigned value);
void mrf_write(unsigned regno, unsigned value);
unsigned mrf_read(unsigned regno);
void mrf_write_array(unsigned regno, const u_int8_t *src, unsigned nbytes);
void mrf_read_array(unsigned regno, u_int8_t *dest, unsigned nbytes);
Six groups of RAWxxx registers provide service for packet transfer of data and management messages:
| Group | Description |
|---|---|
| RAW0_xxx | Receive TCP/IP data |
| RAW1_xxx | Transmit TCP/IP data |
| RAW2_xxx | Receive management messages |
| RAW3_xxx | Transmit management messages |
| RAW4_xxx | Not used |
| RAW5_xxx | Not used |
Every RAW group consists of five registers:
| Register | Size | Description |
|---|---|---|
| RAWx_CTRL0 | 16-bit | Transfer direction, destination and size of message |
| RAWx_CTRL1 | 16-bit | Size of received message |
| RAWx_DATA | 8-bit | Data FIFO |
| RAWx_INDEX | 16-bit | Byte offset in the data area |
| RAWx_STATUS | 16-bit | Status: busy or idle |
In the driver, the following functions implement RAW operations:
void mrf_raw_init(void);
unsigned mrf_raw_move(unsigned raw_id, unsigned raw_obj, int raw_is_destination, unsigned size);
void mrf_raw_seek(unsigned raw_id, unsigned index);
void mrf_raw_read(unsigned raw_id, u_int8_t *dest, unsigned nbytes);
void mrf_raw_write(unsigned raw_id, const u_int8_t *src, unsigned nbytes);
void mrf_raw_pread(unsigned raw_id, u_int8_t *dest, unsigned nbytes, unsigned offset);
void mrf_raw_pwrite(unsigned raw_id, const u_int8_t *src, unsigned nbytes, unsigned offset);
Byte 0 of the management message is always WF_TYPE_MGMT_REQUEST.
| Byte 1: subtype | Byte 2 | Byte 3 | Byte 4... | Reply |
|---|---|---|---|---|
| SET_PARAM | 0 | param_id | data | -- |
| GET_PARAM | 0 | param_id | -- | N bytes |
| SET_POWER_MODE | mode | -- | -- | -- |
| CP_CREATE_PROFILE | -- | -- | -- | 1 byte |
| CP_SET_ELEMENT | cpid | elem_id | data_len, data | -- |
| CP_GET_ELEMENT | cpid | elem_id | -- | N bytes |
| CA_SET_ELEMENT | element_id | data_len | data | -- |
| CA_GET_ELEMENT | element_id | 0 | -- | N bytes |
| CM_CONNECT | cpid | 0 | -- | -- |
| CM_DISCONNECT | -- | -- | -- | -- |
| CM_GET_CONNECTION_STATUS | -- | -- | -- | 1 byte |
| SCAN_START | cpid | 0 | -- | -- |
| SCAN_GET_RESULTS | index | k | -- | 1+56*k bytes |
Two functions provide generic management message functionality in the driver:
void mrf_mgmt_send(u_int8_t *header, unsigned header_len,
u_int8_t *data, unsigned data_len, int free_response);
void mrf_mgmt_send_receive(u_int8_t *header, unsigned header_len,
u_int8_t *reply, unsigned reply_len, unsigned offset);
GET_PARAM and SET_PARAM management messages provide access to the parameters of Wi-Fi transceiver.
| Parameter ID | Mode | Size | Value |
|---|---|---|---|
| SYSTEM_VERSION | R | 2 bytes | ROM and patch version numbers |
| FACTORY_TX_POWER | R | 2 bytes | Get max and min transmit power limits (9..18) |
| STAT_COUNTERS | R | 72 bytes | Get statistics counters |
| MRF24WB0M | W | 1 byte | 1 - enable MRF24WB0M mode |
| YIELD_PASSPHRASE_TOHOST | W | 1 byte | 1 - Allow host to convert pass phrase to key in WPS WPA-PSK |
| REGIONAL_DOMAIN | RW | 1 byte | 0 - FCC region (available channels 1...11); 2 - ETSI region (available channels 1...13); 7 - Other (available channels 1...14) |
| MAC_ADDRESS | RW | 6 bytes | MAC address value |
| CONFIRM_DATA_TX_REQ | W | 1 byte | Enable/disable the Tx data confirm message |
| TX_MODE | W | 1 byte | 0 - 802.11g data rates; 1 - 802.11b data rates; 2 - legacy data rates |
| RTS_THRESHOLD | W | 2 bytes | 2347 by default |
| SET_PSK | W | 32 bytes | PSK key |
| LINK_DOWN_THRESHOLD | W | 1 byte | Number of missed acks before connection lost (0 - keep trying forever) |
| COMPARE_ADDRESS | W | 8 bytes | Control the multicast filter |
The following functions in the driver implement parameter control messages:
unsigned mrf_get_system_version();
unsigned mrf_get_max_power();
void mrf_get_stats(u_int32_t stats[18]);
void mrf_enable_module_operation();
void mrf_yield_passphrase_to_host();
void mrf_set_regional_domain(unsigned value);
unsigned mrf_get_regional_domain();
void mrf_set_mac_address(u_int8_t address[6]);
void mrf_get_mac_address(u_int8_t address[6]);
void mrf_set_tx_confirm(unsigned enable);
void mrf_set_tx_mode(unsigned mode);
void mrf_set_rts_threshold(unsigned level);
void mrf_set_psk(u_int8_t key[32]);
void mrf_set_link_down_threshold(unsigned level);
void mrf_set_multicast_filter(unsigned filter_id, u_int8_t address[6]);
Connection Profile messages have the following structure:
- Byte 0: WF_TYPE_MGMT_REQUEST
- Byte 1: WF_SUBTYPE_CP_SET_ELEMENT
- Byte 2: connection profile ID, obtained by mrf_profile_create() function. MRF24G can have up to two active connection profiles.
- Byte 3: element id CP_ELEMENT_xxx (see table below)
- Byte 4: data length in bytes
- Bytes 5...N: data
| Element ID | Mode | Size | Value |
|---|---|---|---|
| SSID | RW | 0..32 | Set network name (service id) |
| NETWORK_TYPE | W | 1 | Set network type: infrastructure or adhoc |
| SSID_TYPE | W | 1 | Set hidden mode for adhoc network |
| SECURITY | W | 7 + N | Set security type (Open/WEP/WPA/WPS) and password |
| BSSID | W | 6 | Set basic service ID |
| ADHOC_BEHAVIOR | W | 1 | Set adhoc network behavior: connect and start, connect only, start only |
| READ_WPS_CRED | R | 110 | Read WPS credentials |
Functions:
unsigned mrf_profile_create(void);
void mrf_profile_set_ssid(unsigned cpid, u_int8_t *ssid, unsigned ssid_len);
unsigned mrf_profile_get_ssid(unsigned cpid, u_int8_t *ssid);
void mrf_profile_set_network_type(unsigned cpid, unsigned nettype);
void mrf_profile_set_hidden(unsigned cpid, int hidden);
void mrf_profile_set_open(unsigned cpid);
void mrf_profile_set_wep(unsigned cpid, unsigned type, unsigned key_index, u_int8_t *key, unsigned key_len);
void mrf_profile_set_wpa(unsigned cpid, unsigned type, u_int8_t *key, unsigned key_len);
void mrf_profile_set_wps(unsigned cpid, unsigned type, u_int8_t *pin, unsigned pin_len);
void mrf_profile_set_bssid(unsigned cpid, u_int8_t *bssid);
void mrf_profile_set_adhoc_mode(unsigned cpid, int mode);
void mrf_profile_get_wps_credentials(unsigned cpid, wps_credentials_t *cred);
Connection Algorithm messages have the following structure:
- Byte 0: WF_TYPE_MGMT_REQUEST
- Byte 1: WF_SUBTYPE_CA_SET_ELEMENT
- Byte 2: element id CA_ELEMENT_xxx (see table below)
- Byte 3: data length in bytes
- Bytes 4...N: data
| Element ID | Mode | Size | Value |
|---|---|---|---|
| LIST_RETRY_COUNT | W | 1 | Set number of attempts to regain a connection (0 - don't try; 255 - try forever) |
| DEAUTH_ACTION | W | 1 | Set deauthenticated action: whether to attempt to reconnect |
| BEACON_TIMEOUT | W | 1 | Set number of missed beacons before connection loat (0 - don't count) |
| BEACON_TIMEOUT_ACTION | W | 1 | Set beacon timeout action: whether to attempt to reconnect |
| CHANNEL_LIST | W | 1...N | Set list of channels |
| SCANTYPE | W | 1 | Set scan type |
| SCAN_COUNT | W | 1 | Set scan count |
| MIN_CHANNEL_TIME | W | 2 | Set min channel scan time, msec |
| MAX_CHANNEL_TIME | W | 2 | Set max channel scan time, msec |
| PROBE_DELAY | W | 2 | Set scan probe delay, usec |
| BEACON_PERIOD | W | 2 | Set beacon period, msec |
| RSSI | W | 1 | Set RSSI level |
| LISTEN_INTERVAL | W | 2 | Set Listen interval |
| DTIM_INTERVAL | W | 2 | Set Dtim interval |
Functions:
void mrf_conn_set_mode(unsigned retry_count, unsigned deauth_action, unsigned beacon_timeout, unsigned beacon_timeout_action);
void mrf_conn_set_channels(u_int8_t *channel_list, unsigned num_channels);
void mrf_conn_set_scan(unsigned scan_type, unsigned scan_count, unsigned min_channel_msec, unsigned max_channel_msec, unsigned probe_delay_usec);
void mrf_conn_set_adhoc(unsigned cpid, int hidden_ssid, unsigned beacon_msec, unsigned mode);
void mrf_conn_set_rssi(unsigned value);
void mrf_conn_set_listen_interval(unsigned value);
void mrf_conn_set_dtim_interval(unsigned value);
void mrf_connect(unsigned cpid);
void mrf_disconnect(void);
int mrf_conn_get_state(void);
