#include "hspi.h"
//#include <stdio.h>
//#include <string.h>
#include "py/nlr.h"
#include "py/obj.h"
#include "py/runtime.h"
#include "py/binary.h"
#include "portmodules.h"
STATIC mp_obj_t hspi_txchunk(mp_obj_t data) {
// for offset in range(0, len(buf), 10): # iterate trough data 10 bytes at the time
// sdata = buf[offset : offset + 10] # buf is a bytearray
// hspitxchunk.send(sdata)
if (!MP_OBJ_IS_TYPE(data, &mp_type_bytearray)) {
nlr_raise(mp_obj_new_exception_msg(&mp_type_ValueError, "takes bytearray"));
}
// uint8_t dlen;
// dlen = mp_obj_len(data);
mp_buffer_info_t bufinfo;
mp_get_buffer_raise(data, &bufinfo, MP_BUFFER_READ);
// const char *str = mp_obj_str_get_str(data);
// for (; *str; ++str) {
// int chr = *(uint8_t*)str;
// }
uint16_t tat = bufinfo.len / 10;
uint16_t trm = bufinfo.len % 10;
uint8_t nbytes = 10;
for (uint32_t t = 0; t < (tat + 1); t++) {
if (t == tat) { //remainder bytes?
nbytes = trm;
}
uint8_t cmdbits = 0;
uint32_t addrbits = 0;
uint32_t doutbits = 0;
uint8_t cshift = 0;
uint8_t ashift = 0;
uint8_t dshift = 0;
for (uint8_t bl = 0; bl < nbytes; bl++)
{
if (cmdbits < 16) {
cmdbits = cmdbits + 8;
cshift += 1;
}
else {
if (addrbits < 32) {
addrbits = addrbits + 8;
ashift += 1;
}
else {
if (doutbits < 32) {
doutbits = doutbits + 8;
dshift += 1;
}
else {
break;
}
}
}
}
uint16_t cmddata = 0;
uint32_t addrdata = 0;
uint32_t doutdata = 0;
const uint8_t *p = (const uint8_t*)bufinfo.buf;
p = &p[t * 10];
for (uint8_t n = 0; n < 4; n++)
{
if (n <= 1) {
if (((n + 1) * 8) <= cmdbits) {
cmddata |= (p[n] << (8 * (1 - n)));
}
}
if (addrbits != 0) {
if (((n + 1) * 8) <= addrbits) {
addrdata |= (p[n + 2] << (8 * (3 - n)));
}
}
if (doutbits != 0) {
if (((n + 1) * 8) <= doutbits) {
doutdata |= (p[n + 6] << (8 * (3 - n)));
}
}
}
cmddata = cmddata >> ((2 - cshift) * 8);
addrdata = addrdata >> ((4 - ashift) * 8);
doutdata = doutdata >> ((4 - dshift) * 8);
while (spi_busy(1)) {}; // Wait for SPI to be ready
// Enable SPI Functions
// Disable MOSI, MISO, ADDR, COMMAND, DUMMY in case previously set.
CLEAR_PERI_REG_MASK(SPI_USER(1), SPI_USR_MOSI | SPI_USR_MISO | SPI_USR_COMMAND | SPI_USR_ADDR | SPI_USR_DUMMY);
// Setup Bitlengths
WRITE_PERI_REG(SPI_USER1(1),
// Number of bits in Address
((addrbits - 1) & SPI_USR_ADDR_BITLEN) << SPI_USR_ADDR_BITLEN_S |
// Number of bits to Send
((doutbits - 1) & SPI_USR_MOSI_BITLEN) << SPI_USR_MOSI_BITLEN_S);
// Setup Command Data
if (cmdbits) {
// Enable COMMAND function in SPI module
SET_PERI_REG_MASK(SPI_USER(1), SPI_USR_COMMAND);
// Align command data to high bits
uint16_t command = cmddata << (16 - cmdbits);
// Swap byte order
command = ((command >> 8) & 0xff) | ((command << 8) & 0xff00);
WRITE_PERI_REG(SPI_USER2(1), (
(((cmdbits - 1) & SPI_USR_COMMAND_BITLEN) << SPI_USR_COMMAND_BITLEN_S) |
(command & SPI_USR_COMMAND_VALUE)
));
}
// Setup Address Data
if (addrbits) {
// Enable ADDRess function in SPI module
SET_PERI_REG_MASK(SPI_USER(1), SPI_USR_ADDR);
// Align address data to high bits
WRITE_PERI_REG(SPI_ADDR(1), addrdata << (32 - addrbits));
}
// Setup DOUT data
if (doutbits) {
// Enable MOSI function in SPI module
SET_PERI_REG_MASK(SPI_USER(1), SPI_USR_MOSI);
// Copy data to W0
if (READ_PERI_REG(SPI_USER(1))&SPI_WR_BYTE_ORDER) {
WRITE_PERI_REG(SPI_W0(1), doutdata << (32 - doutbits));
}
else {
WRITE_PERI_REG(SPI_W0(1), doutdata);
}
}
// Begin SPI Transaction
SET_PERI_REG_MASK(SPI_CMD(1), SPI_USR);
}
// Transaction completed
return mp_const_none; //return None
}
STATIC MP_DEFINE_CONST_FUN_OBJ_1(hspitxchunk_send_obj, hspi_txchunk);
//STATIC MP_DEFINE_CONST_FUN_OBJ_VAR_BETWEEN(hspitxchunk_send_obj, 1, 10, hspi_txchunk);
// declare python module
STATIC const mp_map_elem_t hspitxchunk_globals_table[] = {
{ MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR_hspitxchunk) },
{ MP_OBJ_NEW_QSTR(MP_QSTR_send), (mp_obj_t)&hspitxchunk_send_obj },
};
STATIC MP_DEFINE_CONST_DICT(mp_module_hspitxchunk_globals, hspitxchunk_globals_table);
const mp_obj_module_t mp_module_hspitxchunk = {
.base = { &mp_type_module },
//.name = MP_QSTR_hspitxchunk, // depricated
.globals = (mp_obj_dict_t*)&mp_module_hspitxchunk_globals,
};
// end declaration